mirror of
https://github.com/bstansell/conserver.git
synced 2025-06-24 09:46:39 +00:00
Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
29b909ee59 | |||
aea0e2a547 | |||
9eed9f2d8f | |||
25a4dcb0fd | |||
75cfd02f7a | |||
ad7a90dd69 |
76
CHANGES
76
CHANGES
@ -1,6 +1,80 @@
|
||||
CHANGES
|
||||
=======
|
||||
|
||||
version 8.1.3 (Mar 22, 2004):
|
||||
- fixed small memory and file descriptor leak in client when
|
||||
using '^Ec;'
|
||||
- '^Ec;' now only disconnects from the previous console only
|
||||
after a successfully move to a new console, allowing you to
|
||||
abort the move - suggested by Christopher T. Beers
|
||||
<ctbeers@syr.edu>
|
||||
|
||||
version 8.1.2 (Mar 11, 2004):
|
||||
- better handling of client command (^Ec|) when user is bumped,
|
||||
conserver is reconfigured, etc
|
||||
- added 'initsubst' option for 'initcmd' substitutions like
|
||||
'devicesubst' and 'execsubst' - based on patch by Bill
|
||||
Sommerfeld <sommerfeld@east.sun.com>
|
||||
- modified and added to *subst (initsubst, etc) syntax to allow
|
||||
for flexibility and future enhancement
|
||||
- changed 'port' and 'portinc' minimums from 1 to 0 - it allows
|
||||
more flexibility and helps with 0-based counting
|
||||
- removed unportable sys/cdefs.h from contrib/chat/chat.c -
|
||||
patch by Bill Sommerfeld <sommerfeld@east.sun.com>
|
||||
- added --with-extmsgs configure switch to enable entertaining
|
||||
messages
|
||||
- marked various undocumented client commands as deprecated so
|
||||
that they can be removed in a future version
|
||||
- added ability to "move" to a new console via '^Ec;' -
|
||||
suggested by Christopher T. Beers <ctbeers@syr.edu>
|
||||
- added a dump of console information when -S is used twice -
|
||||
suggested by Todd Stansell <todd@stansell.org>
|
||||
|
||||
version 8.1.1 (Feb 10, 2004):
|
||||
- fixed mistake in Makefiles where rpmbuild fails - reported by
|
||||
Martin Evans <m.d.t.evans@qmul.ac.uk>
|
||||
- fixed a couple typos - reported by Matt Selsky
|
||||
<selsky@columbia.edu>
|
||||
|
||||
version 8.1.0 (Jan 18, 2004):
|
||||
- fixes for HP-UX compilation - patch by Petter Reinholdtsen
|
||||
<pere@hungry.com>
|
||||
- fixes for compilation under various operating systems -
|
||||
patch by Albert Chin <conserver-users@mlists.thewrittenword.com>
|
||||
- added a 'protocol' option for either 'telnet' or 'raw' socket
|
||||
communication - also reflected in -i output
|
||||
- changed the client/server protocol to use 0xff as a command
|
||||
character for sending control commands - similiar to the
|
||||
telnet protocol - improves the ^Ec| interaction
|
||||
- client -E option now disables ssl encryption attempts, useful
|
||||
for broken SSL environents - suggested by Graydon Dodson
|
||||
<grdodson@lexmark.com>
|
||||
- bad error message connecting non-ssl client with ssl-required
|
||||
server - reported by Graydon Dodson <grdodson@lexmark.com>
|
||||
- added note about pam configuration to conserver.passwd.man -
|
||||
suggested by Erik Sjolund <erik.sjolund@sbc.su.se>
|
||||
- improved telnet protocol option handling such that connections
|
||||
to standard telnet ports should work properly
|
||||
|
||||
version 8.0.9 (Dec 10, 2003):
|
||||
- fixed major bug in connect() handling which causes most
|
||||
socket-based consoles to timeout after 10 seconds - reported
|
||||
by Tom Rataski <trataski@intlsteel.com>
|
||||
- added a couple details to the 'logfilemax' manpage entry
|
||||
|
||||
version 8.0.8 (Dec 2, 2003):
|
||||
- added client ^Ec| sequence for running a command on the client
|
||||
and having it's I/O directed to the console - inspired by
|
||||
discussions with David Williamson
|
||||
<david+conserver@williamsons.net> years ago ;-)
|
||||
- touched up Makefiles to test against .h files
|
||||
- fixed inability to replay the console log while the console is
|
||||
down - reported by Matt Selsky <selsky@columbia.edu>
|
||||
- added a console 'logfilemax' option for rotating the console
|
||||
logfile once the file is greater than the specified size
|
||||
- added sample configuration files to conserver.cf/samples
|
||||
- tweaked some failure messages and initcmd notifications
|
||||
|
||||
version 8.0.7 (Nov 20, 2003):
|
||||
- renamed util.[ch] to cutil.[ch] to prevent name conflict with
|
||||
system util.h, reordered some #includes, and fixed a configure
|
||||
@ -624,5 +698,5 @@ before version 6.05:
|
||||
and enhancements of various types were applied.
|
||||
|
||||
#
|
||||
# $Id: CHANGES,v 1.135 2003/11/20 14:48:29 bryan Exp $
|
||||
# $Id: CHANGES,v 1.162 2004/03/23 00:55:04 bryan Exp $
|
||||
#
|
||||
|
21
INSTALL
21
INSTALL
@ -10,6 +10,25 @@ Upgrading?
|
||||
new features added to the client if you're considering *not*
|
||||
upgrading.
|
||||
|
||||
Version 8.1.3
|
||||
- The '^Ec;' sequence won't work correctly with 8.1.2 (where it
|
||||
was introduced).
|
||||
|
||||
Version 8.1.2
|
||||
- The 'devicesubst' and 'execsubst' formats have changed from
|
||||
8.1.1. It's fairly simple to update your config file to the
|
||||
new format...just check the conserver.cf manpage. Sorry for
|
||||
having to change things, but it's for a good reason (I should
|
||||
have though ahead when designing the original format).
|
||||
|
||||
Version 8.1.0
|
||||
|
||||
- The client/server protocol has changed to better protect 8-bit
|
||||
data and to allow programs invoked with '^Ec|' not have to
|
||||
worry about accidentally sending the escape sequence to the
|
||||
server. Though it will look like things are mostly
|
||||
backward-compatible, don't count on it and just upgrade.
|
||||
|
||||
Version 8.0.2
|
||||
|
||||
- I've added a '^Ec;' sequence to allow the client to signal the
|
||||
@ -255,5 +274,5 @@ Other Information And Gotchas
|
||||
|
||||
|
||||
#
|
||||
# $Id: INSTALL,v 1.34 2003/10/03 17:52:31 bryan Exp $
|
||||
# $Id: INSTALL,v 1.37 2004/03/23 00:55:04 bryan Exp $
|
||||
#
|
||||
|
38
TODO
38
TODO
@ -11,13 +11,10 @@ Bryan Stansell
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
- Telnet protocol should be improved
|
||||
- Not even RFC 854 compliant
|
||||
- Option negotiation ignored - should we negotiate anything?
|
||||
- Not even RFC 854 compliant...or maybe it is (as of 8.1.0)
|
||||
- Option negotiation semi-ignored - should we negotiate anything more?
|
||||
- Others?
|
||||
|
||||
- better shadow file support
|
||||
- what does this mean? i've forgotten.
|
||||
|
||||
- syslog?
|
||||
Daniel E. Singer <des@cs.duke.edu> would like to see it - especially
|
||||
in regards to --use-libwrap code
|
||||
@ -27,14 +24,20 @@ Bryan Stansell
|
||||
- hpux has bigcrypt() also, which we support, so maybe we're covered
|
||||
|
||||
- config file examples for various configurations
|
||||
- sample conserver.cf has some...but it's not explained well
|
||||
|
||||
- per-line timestamps
|
||||
- only when not connected?
|
||||
|
||||
- pipe input/output (console <-> program) via 'console'
|
||||
- some apps (net-ups thing, gdb) might need to talk to user
|
||||
- ^Ec| does this, but the interact with user bits might not work
|
||||
- actually, ^Ec| does work right with 8.1.0...one change that might
|
||||
be nice is the ability to NOT watch the i/o pass to the local
|
||||
command - try sending a big file to the local host with xmodem.
|
||||
|
||||
- autologout? setting per console? gack, would have to interpret data.
|
||||
- this will never happen...i don't want to interpret data
|
||||
|
||||
- "listen" capability (watch all/multiple consoles)
|
||||
|
||||
@ -47,6 +50,7 @@ Bryan Stansell
|
||||
- passphrase...hmmm..could really use some sort of send/expect
|
||||
thing here. you could write a wrapper script of sorts, but it
|
||||
really would be nice to have a raw socket and do the right thing.
|
||||
- this does work, using the 'initcmd' option, so, all done?
|
||||
|
||||
- cyclades ts1000/2000 port : "Moses, Joel" <jmoses@deloitte.com>
|
||||
|
||||
@ -58,8 +62,7 @@ Bryan Stansell
|
||||
|
||||
- server -M flag should accept multiple addresses (comma separated)
|
||||
- should client as well?
|
||||
|
||||
- logfile rotation based on size
|
||||
- this may never happen...does anyone really need it?
|
||||
|
||||
- automatic log rotation in general : Egan Ford <egan@us.ibm.com>
|
||||
|
||||
@ -70,6 +73,7 @@ Bryan Stansell
|
||||
|
||||
- suggestions by Trevor Fiatal <trevor@seven.com>
|
||||
- include server hostname on 'console -x' output
|
||||
- i think the -i output covers it, but maybe not
|
||||
|
||||
- ability to configure strings to be sent to a console periodically :
|
||||
Greg A. Woods <woods@planix.com>
|
||||
@ -79,13 +83,29 @@ Bryan Stansell
|
||||
|
||||
- redefine client escape sequence in conserver.cf : Toby Gerhart
|
||||
<toby.gerhart@eds.com>
|
||||
- not even sure if this is possible w/o confusing the client,
|
||||
but maybe with the new 8.1.0 client-server protocol, we can!
|
||||
|
||||
- send a string when connected to a console, so you can set the
|
||||
xterm title, for example : Richard Threadgill <richardt@tellme.com>
|
||||
- this probably requires a client config file, so could play well
|
||||
with the client config file requirement above
|
||||
|
||||
- allows for very long replays (hundres of lines) : John Stoffel
|
||||
- allow for very long replays (hundres of lines) : John Stoffel
|
||||
<stoffel@lucent.com>
|
||||
|
||||
- log rotation by date : Tom Pachla <tom.pachla@nlc-bnc.ca>
|
||||
|
||||
- client config file (for -M, etc?) : Erik Sjolund
|
||||
<erik.sjolund@sbc.su.se>
|
||||
|
||||
- strict file permission checks on conserver.passwd/conserver.cf : Erik
|
||||
Sjolund <erik.sjolund@sbc.su.se>
|
||||
|
||||
- embedded startup delays per remote host...or "group" of consoles in
|
||||
some way 'cause some ssh connections to console servers need
|
||||
significant throttling : Jay McCanta <mccantaj@amgen.com>
|
||||
|
||||
#
|
||||
# $Id: TODO,v 1.42 2003/11/15 17:08:15 bryan Exp $
|
||||
# $Id: TODO,v 1.47 2004/03/12 17:34:49 bryan Exp $
|
||||
#
|
||||
|
@ -31,6 +31,8 @@ ALL = autologin
|
||||
|
||||
all: $(ALL)
|
||||
|
||||
$(AUTOLOGIN_OBJS): $(AUTOLOGIN_HDRS)
|
||||
|
||||
autologin: $(AUTOLOGIN_OBJS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o autologin $(AUTOLOGIN_OBJS) $(LIBS)
|
||||
|
||||
|
4
compat.h
4
compat.h
@ -287,6 +287,10 @@ typedef int socklen_t;
|
||||
#define ONLRET 0
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_SET
|
||||
#define SEEK_SET L_SET
|
||||
#endif
|
||||
|
||||
#ifndef PARAMS
|
||||
# if PROTOTYPES
|
||||
# define PARAMS(protos) protos
|
||||
|
44
config.guess
vendored
44
config.guess
vendored
@ -3,7 +3,7 @@
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2003-10-16'
|
||||
timestamp='2004-03-12'
|
||||
|
||||
# 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
|
||||
@ -197,12 +197,18 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
|
||||
echo "${machine}-${os}${release}"
|
||||
exit 0 ;;
|
||||
amd64:OpenBSD:*:*)
|
||||
echo x86_64-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
amiga:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
arc:OpenBSD:*:*)
|
||||
echo mipsel-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
cats:OpenBSD:*:*)
|
||||
echo arm-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
hp300:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
@ -239,10 +245,24 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
*:OpenBSD:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:ekkoBSD:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
macppc:MirBSD:*:*)
|
||||
echo powerppc-unknown-mirbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:MirBSD:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
alpha:OSF1:*:*)
|
||||
if test $UNAME_RELEASE = "V4.0"; then
|
||||
case $UNAME_RELEASE in
|
||||
*4.0)
|
||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
|
||||
fi
|
||||
;;
|
||||
*5.*)
|
||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
|
||||
;;
|
||||
esac
|
||||
# According to Compaq, /usr/sbin/psrinfo has been available on
|
||||
# OSF/1 and Tru64 systems produced since 1995. I hope that
|
||||
# covers most systems running today. This code pipes the CPU
|
||||
@ -280,11 +300,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
"EV7.9 (21364A)")
|
||||
UNAME_MACHINE="alphaev79" ;;
|
||||
esac
|
||||
# A Pn.n version is a patched version.
|
||||
# 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.
|
||||
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
exit 0 ;;
|
||||
Alpha*:OpenVMS:*:*)
|
||||
echo alpha-hp-vms
|
||||
@ -405,6 +426,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
|
||||
echo m68k-unknown-mint${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
m68k:machten:*:*)
|
||||
echo m68k-apple-machten${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
powerpc:machten:*:*)
|
||||
echo powerpc-apple-machten${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
@ -829,6 +853,9 @@ EOF
|
||||
ia64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit 0 ;;
|
||||
m32r*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit 0 ;;
|
||||
m68*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit 0 ;;
|
||||
@ -997,6 +1024,9 @@ EOF
|
||||
i*86:atheos:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-atheos
|
||||
exit 0 ;;
|
||||
i*86:syllable:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-syllable
|
||||
exit 0 ;;
|
||||
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
|
||||
echo i386-unknown-lynxos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
@ -1183,7 +1213,7 @@ EOF
|
||||
*:QNX:*:4*)
|
||||
echo i386-pc-qnx
|
||||
exit 0 ;;
|
||||
NSR-[DGKLNPTVWY]:NONSTOP_KERNEL:*:*)
|
||||
NSR-?:NONSTOP_KERNEL:*:*)
|
||||
echo nsr-tandem-nsk${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:NonStop-UX:*:*)
|
||||
@ -1227,8 +1257,8 @@ EOF
|
||||
SEI:*:*:SEIUX)
|
||||
echo mips-sei-seiux${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:DRAGONFLY:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-dragonfly${UNAME_RELEASE}
|
||||
*:DragonFly:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
|
||||
exit 0 ;;
|
||||
esac
|
||||
|
||||
|
@ -324,6 +324,9 @@
|
||||
/* Defined if we trust reverse DNS */
|
||||
#undef TRUST_REVERSE_DNS
|
||||
|
||||
/* Defined if we produce extended messages */
|
||||
#undef USE_EXTENDED_MESSAGES
|
||||
|
||||
/* use tcp_wrappers libwrap */
|
||||
#undef USE_LIBWRAP
|
||||
|
||||
@ -348,3 +351,6 @@
|
||||
|
||||
/* Define if <signal.h> does not define sig_atomic_t */
|
||||
#undef sig_atomic_t
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> does not define. */
|
||||
#undef size_t
|
||||
|
34
config.sub
vendored
34
config.sub
vendored
@ -3,7 +3,7 @@
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2003-11-03'
|
||||
timestamp='2004-03-12'
|
||||
|
||||
# This file is (in principle) common to ALL GNU software.
|
||||
# The presence of a machine in this file suggests that SOME GNU software
|
||||
@ -237,7 +237,7 @@ case $basic_machine in
|
||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||
| i370 | i860 | i960 | ia64 \
|
||||
| ip2k | iq2000 \
|
||||
| m32r | m68000 | m68k | m88k | mcore \
|
||||
| m32r | m32rle | m68000 | m68k | m88k | mcore \
|
||||
| mips | mipsbe | mipseb | mipsel | mipsle \
|
||||
| mips16 \
|
||||
| mips64 | mips64el \
|
||||
@ -262,7 +262,7 @@ case $basic_machine in
|
||||
| pyramid \
|
||||
| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
|
||||
| sh64 | sh64le \
|
||||
| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
|
||||
| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \
|
||||
| strongarm \
|
||||
| tahoe | thumb | tic4x | tic80 | tron \
|
||||
| v850 | v850e \
|
||||
@ -308,7 +308,7 @@ case $basic_machine in
|
||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||
| i*86-* | i860-* | i960-* | ia64-* \
|
||||
| ip2k-* | iq2000-* \
|
||||
| m32r-* \
|
||||
| m32r-* | m32rle-* \
|
||||
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
|
||||
| m88110-* | m88k-* | mcore-* \
|
||||
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
|
||||
@ -336,7 +336,7 @@ case $basic_machine in
|
||||
| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
|
||||
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
|
||||
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
|
||||
| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
|
||||
| sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
|
||||
| tahoe-* | thumb-* \
|
||||
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
|
||||
| tron-* \
|
||||
@ -363,6 +363,9 @@ case $basic_machine in
|
||||
basic_machine=a29k-amd
|
||||
os=-udi
|
||||
;;
|
||||
abacus)
|
||||
basic_machine=abacus-unknown
|
||||
;;
|
||||
adobe68k)
|
||||
basic_machine=m68010-adobe
|
||||
os=-scout
|
||||
@ -380,6 +383,9 @@ case $basic_machine in
|
||||
amd64)
|
||||
basic_machine=x86_64-pc
|
||||
;;
|
||||
amd64-*)
|
||||
basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
amdahl)
|
||||
basic_machine=580-amdahl
|
||||
os=-sysv
|
||||
@ -439,12 +445,20 @@ case $basic_machine in
|
||||
basic_machine=j90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
cr16c)
|
||||
basic_machine=cr16c-unknown
|
||||
os=-elf
|
||||
;;
|
||||
crds | unos)
|
||||
basic_machine=m68k-crds
|
||||
;;
|
||||
cris | cris-* | etrax*)
|
||||
basic_machine=cris-axis
|
||||
;;
|
||||
crx)
|
||||
basic_machine=crx-unknown
|
||||
os=-elf
|
||||
;;
|
||||
da30 | da30-*)
|
||||
basic_machine=m68k-da30
|
||||
;;
|
||||
@ -1067,7 +1081,7 @@ case $basic_machine in
|
||||
sh64)
|
||||
basic_machine=sh64-unknown
|
||||
;;
|
||||
sparc | sparcv9 | sparcv9b)
|
||||
sparc | sparcv8 | sparcv9 | sparcv9b)
|
||||
basic_machine=sparc-sun
|
||||
;;
|
||||
cydra)
|
||||
@ -1140,8 +1154,9 @@ case $os in
|
||||
| -aos* \
|
||||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||
| -hiux* | -386bsd* | -knetbsd* | -netbsd* | -openbsd* | -kfreebsd* | -freebsd* | -riscix* \
|
||||
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
|
||||
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
|
||||
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
||||
| -chorusos* | -chorusrdb* \
|
||||
@ -1215,6 +1230,9 @@ case $os in
|
||||
-atheos*)
|
||||
os=-atheos
|
||||
;;
|
||||
-syllable*)
|
||||
os=-syllable
|
||||
;;
|
||||
-386bsd)
|
||||
os=-bsd
|
||||
;;
|
||||
|
15
configure.in
15
configure.in
@ -16,6 +16,7 @@ AH_TEMPLATE([HAVE_OPENSSL], [have openssl support])
|
||||
AH_TEMPLATE([HAVE_DMALLOC], [have dmalloc support])
|
||||
AH_TEMPLATE([HAVE_SA_LEN],[Defined if sa_len member exists in struct sockaddr])
|
||||
AH_TEMPLATE([TRUST_REVERSE_DNS],[Defined if we trust reverse DNS])
|
||||
AH_TEMPLATE([USE_EXTENDED_MESSAGES],[Defined if we produce extended messages])
|
||||
|
||||
dnl ### Normal initialization. ######################################
|
||||
AC_INIT
|
||||
@ -215,6 +216,19 @@ AC_ARG_WITH(trustrevdns,
|
||||
;;
|
||||
esac],[AC_MSG_RESULT(no)])
|
||||
|
||||
AC_MSG_CHECKING(whether to display extended messages)
|
||||
AC_ARG_WITH(extmsgs,
|
||||
AC_HELP_STRING([--with-extmsgs],[Produce extended messages]),
|
||||
[case "$withval" in
|
||||
yes)
|
||||
AC_DEFINE(USE_EXTENDED_MESSAGES)
|
||||
AC_MSG_RESULT(yes)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT(no)
|
||||
;;
|
||||
esac],[AC_MSG_RESULT(no)])
|
||||
|
||||
dnl ### Check for compiler et al. ###################################
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
@ -256,6 +270,7 @@ AC_HEADER_SYS_WAIT
|
||||
AC_TYPE_MODE_T
|
||||
AC_TYPE_SIGNAL
|
||||
AC_TYPE_PID_T
|
||||
AC_TYPE_SIZE_T
|
||||
|
||||
AC_CHECK_TYPE([sig_atomic_t],,
|
||||
AC_DEFINE(sig_atomic_t, volatile int,
|
||||
|
@ -3,7 +3,8 @@ srcdir = @srcdir@
|
||||
prefix = @prefix@
|
||||
mandir = @mandir@
|
||||
sysconfdir = @sysconfdir@
|
||||
exampledir = $(prefix)/share/examples/conserver
|
||||
datadir = @datadir@
|
||||
exampledir = $(datadir)/examples/conserver
|
||||
|
||||
### Installation programs and flags
|
||||
INSTALL = @INSTALL@
|
||||
|
@ -14,39 +14,53 @@ default cisco { type host; portbase 2000; portinc 1; }
|
||||
default xyplex { type host; portbase 2000; portinc 100; }
|
||||
default iolan { type host; portbase 10000; portinc 1; }
|
||||
|
||||
### set up some custom break sequences
|
||||
break 4 { string "+\d+\d+"; delay 300; }
|
||||
break 5 { string "\033c"; }
|
||||
|
||||
### set the defaults for all the consoles
|
||||
# these get applied before anything else
|
||||
default * {
|
||||
# The '&' character is substituted with the console name
|
||||
logfile /var/consoles/&;
|
||||
# timestamps every hour with activity and break logging
|
||||
timestamp 1hab;
|
||||
# include the 'full' default
|
||||
include full;
|
||||
# master server is localhost
|
||||
master localhost;
|
||||
}
|
||||
|
||||
### define the first terminal server
|
||||
default ts1.conserver.com {
|
||||
# use the xyplex defaults
|
||||
include xyplex;
|
||||
# host to connect to is ts1.conserver.com
|
||||
host ts1.conserver.com;
|
||||
# run login-xyplex when connecting to the term server
|
||||
initcmd /usr/local/sbin/login-xyplex;
|
||||
}
|
||||
|
||||
# now define the consoles on ts1.conserver.com
|
||||
console web1.conserver.com { include ts1.conserver.com; port 2; }
|
||||
# bryan isn't allowed on web1.conserver.com
|
||||
console web1.conserver.com { include ts1.conserver.com; port 2; rw !bryan; }
|
||||
console ns1.conserver.com { include ts1.conserver.com; port 10; }
|
||||
console ns2.conserver.com { include ts1.conserver.com; port 8; }
|
||||
|
||||
### define the second terminal server
|
||||
# this one is a cisco, with simple socket connections
|
||||
default ts2.conserver.com { include cisco; host ts2.conserver.com; }
|
||||
|
||||
# and the consoles
|
||||
# and the consoles on ts2.conserver.com
|
||||
console ldap1.conserver.com { include ts2.conserver.com; port 7; }
|
||||
|
||||
### and now some one-off consoles
|
||||
# we still inherit the '*' default set
|
||||
# a simple ssh invocation
|
||||
console ssh {
|
||||
type exec;
|
||||
exec ssh localhost;
|
||||
# provide a 'message-of-the-day'
|
||||
motd "just a simple ssh to localhost";
|
||||
}
|
||||
|
||||
@ -59,6 +73,39 @@ console ttya {
|
||||
timestamp ""; # no timestamps on this console
|
||||
}
|
||||
|
||||
### define a group of users
|
||||
group sysadmin {
|
||||
users bryan, todd;
|
||||
users dave;
|
||||
}
|
||||
|
||||
### reset the defaults for the next set of consoles
|
||||
# again, these get applied before anything else
|
||||
default * {
|
||||
# The '&' character is substituted with the console name
|
||||
logfile /var/consoles/&;
|
||||
timestamp 5m;
|
||||
rw sysadmin; # use the group defined above
|
||||
master localhost;
|
||||
}
|
||||
|
||||
default cyclades {
|
||||
# sets up /dev/ttyC0 through /dev/ttyC31, for a 32 port card
|
||||
# referenced as ports 1 through 32
|
||||
type device;
|
||||
device /dev/ttyC.;
|
||||
devicesubst .=Pd;
|
||||
portbase -1;
|
||||
portinc 1;
|
||||
host none; # not really used, since devicesubst doesn't use it
|
||||
baud 9600;
|
||||
parity none;
|
||||
}
|
||||
|
||||
console modem1.conserver.com { include cyclades; port 2; break 4; }
|
||||
# todd isn't allowed on modem2.conserver.com
|
||||
console modem2.conserver.com { include cyclades; port 6; rw !todd; }
|
||||
|
||||
### list of clients we allow
|
||||
access * {
|
||||
allowed 10.0.0.0/8 192.168.0.0/16;
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" $Id: conserver.cf.man,v 1.51 2003/11/15 20:00:11 bryan Exp $
|
||||
.TH CONSERVER.CF 5 "2003/11/15" "conserver-8.0.7" "conserver"
|
||||
.\" $Id: conserver.cf.man,v 1.58 2004/02/24 02:59:36 bryan Exp $
|
||||
.TH CONSERVER.CF 5 "2004/02/24" "conserver-8.1.3" "conserver"
|
||||
.SH NAME
|
||||
conserver.cf \- console configuration file for
|
||||
.BR conserver (8)
|
||||
@ -411,33 +411,73 @@ as the access to the console.
|
||||
Only consoles of type ``device'' will use this value.
|
||||
.TP
|
||||
.B devicesubst
|
||||
.RI [ " hp" [ n ] "f "
|
||||
.RI [ c = t [ n ] f "[,...]"
|
||||
| "" ]
|
||||
.br
|
||||
Perform string substitutions on the
|
||||
Perform character substitutions on the
|
||||
.B device
|
||||
value.
|
||||
.I h
|
||||
is the character in
|
||||
.B device
|
||||
to replace with the
|
||||
A series of replacements can be defined by specifying a
|
||||
comma-separated list of
|
||||
.IR c = t [ n ] f
|
||||
sequences where
|
||||
.I c
|
||||
is any printable character,
|
||||
.I t
|
||||
specifies the replacement value,
|
||||
.I n
|
||||
is a field length (optional),
|
||||
and
|
||||
.I f
|
||||
is the format string.
|
||||
.I t
|
||||
can be one of the characters below, catagorized as a string replacement
|
||||
or a numeric replacement, which dictates the use of the
|
||||
.I n
|
||||
and
|
||||
.I f
|
||||
fields.
|
||||
.RS
|
||||
.RS
|
||||
.sp
|
||||
.PD 0
|
||||
.TP
|
||||
String Replacement
|
||||
.TP
|
||||
.B h
|
||||
.B host
|
||||
value and
|
||||
.I p
|
||||
is the character to replace with the
|
||||
value
|
||||
.TP
|
||||
.B c
|
||||
console name
|
||||
.sp
|
||||
.PP
|
||||
Numeric Replacement
|
||||
.TP
|
||||
.B p
|
||||
config
|
||||
.B port
|
||||
value.
|
||||
The
|
||||
.B port
|
||||
value will be formatted to at least
|
||||
value
|
||||
.TP
|
||||
.B P
|
||||
calculated port value
|
||||
.PD
|
||||
.RE
|
||||
.RE
|
||||
.IP
|
||||
For string replacements, if the replacement isn't at least
|
||||
.I n
|
||||
characters, it will be padded with space characters on the left.
|
||||
.I f
|
||||
must be `s'.
|
||||
For numeric replacements, the value will be formatted to at least
|
||||
.I n
|
||||
characters, padded with 0s if
|
||||
.I n
|
||||
begins with a 0, and space characters otherwise.
|
||||
.I f
|
||||
must be either `d' or `x' or `X', specifying a decimal, lower-case
|
||||
hexdecimal, or uppercase hexdecimal representation of
|
||||
.BR port .
|
||||
must be either `d', `x' or `X', specifying a decimal, lower-case
|
||||
hexadecimal, or an uppercase hexadecimal conversion.
|
||||
If the null string (``""'') is used, no replacements will be done.
|
||||
.TP
|
||||
.B exec
|
||||
@ -455,33 +495,15 @@ keyword is specified, conserver will use the command ``/bin/sh -i''.
|
||||
Only consoles of type ``exec'' will use this value.
|
||||
.TP
|
||||
.B execsubst
|
||||
.RI [ " hp" [ n ] "f "
|
||||
.RI [ c = t [ n ] f "[,...]"
|
||||
| "" ]
|
||||
.br
|
||||
Perform string substitutions on the
|
||||
Perform character substitutions on the
|
||||
.B exec
|
||||
value.
|
||||
.I h
|
||||
is the character in
|
||||
.B exec
|
||||
to replace with the
|
||||
.B host
|
||||
value and
|
||||
.I p
|
||||
is the character to replace with the
|
||||
.B port
|
||||
value.
|
||||
The
|
||||
.B port
|
||||
value will be formatted to at least
|
||||
.I n
|
||||
characters, padded with 0s if
|
||||
.I n
|
||||
begins with a 0, and space characters otherwise.
|
||||
.I f
|
||||
must be either `d' or `x' or `X', specifying a decimal, lower-case
|
||||
hexdecimal, or uppercase hexdecimal representation of
|
||||
.BR port .
|
||||
See the
|
||||
.B devicesubst
|
||||
option for an explanation of the format string.
|
||||
If the null string (``""'') is used, no replacements will be done.
|
||||
.TP
|
||||
.B host
|
||||
@ -493,7 +515,13 @@ as the host to connect to for accessing the console.
|
||||
You must also set the
|
||||
.B port
|
||||
option as well.
|
||||
Only consoles of type ``host'' will use this value.
|
||||
Normally, only consoles of type ``host'' will use this value, however
|
||||
if the
|
||||
.BR devicesubst ,
|
||||
.BR execsubst ,
|
||||
or
|
||||
.B initsubst
|
||||
keywords are used in any console type, this value is used.
|
||||
.TP
|
||||
.B idlestring
|
||||
.RI [ " string "
|
||||
@ -519,7 +547,8 @@ The default string is ``\en''.
|
||||
.br
|
||||
Set the idle timeout of the console to
|
||||
.I number
|
||||
seconds. If an `s', `m', or `h' is used after
|
||||
seconds.
|
||||
If an `s', `m', or `h' is used after
|
||||
.IR number ,
|
||||
the specified time is interpreted as seconds, minutes, or hours.
|
||||
Set the timeout to zero to disable the idle timeout (the default).
|
||||
@ -547,18 +576,65 @@ is passed as an argument to ``/bin/sh -ce''.
|
||||
If the null string (``""'') is used, the command is unset and
|
||||
nothing is invoked.
|
||||
.TP
|
||||
.B initsubst
|
||||
.RI [ c = t [ n ] f "[,...]"
|
||||
| "" ]
|
||||
.br
|
||||
Perform character substitutions on the
|
||||
.B initcmd
|
||||
value.
|
||||
See the
|
||||
.B devicesubst
|
||||
option for an explanation of the format string.
|
||||
If the null string (``""'') is used, no replacements will be done.
|
||||
.TP
|
||||
.B logfile
|
||||
.RI [ " filename "
|
||||
| "" ]
|
||||
.br
|
||||
Assign the logfile specified by
|
||||
.I filename
|
||||
to the console. Any occurrence of ``&'' in
|
||||
to the console.
|
||||
Any occurrence of ``&'' in
|
||||
.I filename
|
||||
will be replaced with the name of the console.
|
||||
If the null string (``""'') is used, the logfile name is unset and
|
||||
no logging will occur.
|
||||
.TP
|
||||
.B logfilemax
|
||||
.BR \fInumber\fP [ k | m ]
|
||||
.br
|
||||
Enable automatic rotation of
|
||||
.B logfile
|
||||
once it's size exceeds
|
||||
.I number
|
||||
bytes.
|
||||
Specifying
|
||||
.B k
|
||||
or
|
||||
.B m
|
||||
interpret
|
||||
.I number
|
||||
as kilobytes and megabytes.
|
||||
.I number
|
||||
must be at least 2048 bytes.
|
||||
A value of zero will turn off automatic rotation of
|
||||
.BR logfile .
|
||||
The
|
||||
.B logfile
|
||||
.I filename
|
||||
will be renamed
|
||||
.IR filename -\s-1YYYYMMDD\s0-\s-1HHMMSS\s0,
|
||||
where the extension is the current GMT year, month, day, hour,
|
||||
minute, and second (to prevent issues with clock rollbacks).
|
||||
File sizes are checked every 5 minutes with an additional initial
|
||||
pseudo-random delay of up to one minute (to help prevent all processes
|
||||
checking all consoles simultaneously).
|
||||
2.5% (minimum 100 bytes, maximum 4000 bytes) of the old
|
||||
logfile is read from the end of the file.
|
||||
All data past the first newline is moved (not copied) to the new logfile
|
||||
so that a replay of the console works and starts on a line boundary.
|
||||
.TP
|
||||
.B master
|
||||
.RI [ " hostname " | " ipaddr " ]
|
||||
.br
|
||||
@ -656,7 +732,7 @@ The conserver option
|
||||
.B \-7
|
||||
will set this flag for all consoles.
|
||||
Default is
|
||||
.BR !stiphigh .
|
||||
.BR !striphigh .
|
||||
.TP
|
||||
.B reinitoncc
|
||||
Automatically reinitialize (``bring up'') a downed console when a client
|
||||
@ -725,17 +801,31 @@ The formula used is
|
||||
.BR portbase " + "
|
||||
.BR portinc " * " port .
|
||||
By using proper values in the formula, you can reference ports on a
|
||||
terminal server by their physical numbering of 1 through
|
||||
.IR n .
|
||||
terminal server by their physical numbering of
|
||||
.RI 0.. n
|
||||
or
|
||||
.RI 1.. n
|
||||
(depending on if you like zero-based or one-based numbering).
|
||||
Warning: you can generate a \-1 value with this formula,
|
||||
which will become a very high numbered positive
|
||||
value (since things are stored unsigned).
|
||||
You must also set the
|
||||
.B host
|
||||
option as well.
|
||||
Only consoles of type ``host'' will use this value.
|
||||
Normally, only consoles of type ``host'' will use this value, however
|
||||
if the
|
||||
.BR devicesubst ,
|
||||
.BR execsubst ,
|
||||
or
|
||||
.B initsubst
|
||||
keywords are used in any console type, this value is used.
|
||||
.TP
|
||||
.B portbase
|
||||
.I number
|
||||
.br
|
||||
Set the base value for the port calculation formula.
|
||||
.I number
|
||||
must be 0 or greater.
|
||||
The default is zero.
|
||||
See
|
||||
.B port
|
||||
@ -745,11 +835,28 @@ for the details of the formula.
|
||||
.I number
|
||||
.br
|
||||
Set the increment value for the port calculation formula.
|
||||
.I number
|
||||
must be 0 or greater.
|
||||
The default is one.
|
||||
See
|
||||
.B port
|
||||
for the details of the formula.
|
||||
.TP
|
||||
.B protocol
|
||||
.RB [ " telnet " | " raw " ]
|
||||
.br
|
||||
Set the protocol used to send and receive data from the console.
|
||||
If
|
||||
.B raw
|
||||
is used, all data is sent ``as is'', unprotected by any protocol specification.
|
||||
If
|
||||
.B telnet
|
||||
is used (which is the default), data is encapsulated in the telnet protocol.
|
||||
The
|
||||
.B striphigh
|
||||
console option still applies when data is read by the server, and if enabled,
|
||||
can impact the encapsulation process.
|
||||
.TP
|
||||
.B ro
|
||||
.RI "[ [\fB!\fP]" username ,...
|
||||
| "" ]
|
||||
@ -817,7 +924,8 @@ can be specified to add logging of break sequences sent to the console.
|
||||
.B type
|
||||
.RB [ " device " | " exec " | " host " ]
|
||||
.br
|
||||
Set the type of console. The type
|
||||
Set the type of console.
|
||||
The type
|
||||
.RB `` device ''
|
||||
should be used for local serial ports (also set the
|
||||
.B device
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" $Id: conserver.passwd.man,v 1.9 2003/07/04 20:20:52 bryan Exp $
|
||||
.TH CONSERVER.PASSWD 5 "2003/07/04" "conserver-8.0.7" "conserver"
|
||||
.\" $Id: conserver.passwd.man,v 1.10 2004/01/08 16:12:33 bryan Exp $
|
||||
.TH CONSERVER.PASSWD 5 "2004/01/08" "conserver-8.1.3" "conserver"
|
||||
.SH NAME
|
||||
conserver.passwd \- user access information for
|
||||
.BR conserver (8)
|
||||
@ -59,7 +59,8 @@ in the system
|
||||
If PAM support has been enabled
|
||||
.RB ( --with-pam ),
|
||||
PAM lookups will be done instead of
|
||||
.BR passwd " (or " shadow ") lookups."
|
||||
.BR passwd " (or " shadow ") lookups"
|
||||
(you may need to edit /etc/pam.conf or create /etc/pam.d/conserver).
|
||||
If this field is empty, password checking is bypassed for this user.
|
||||
.SH EXAMPLE
|
||||
.TP 24
|
||||
|
21
conserver.cf/samples/README
Normal file
21
conserver.cf/samples/README
Normal file
@ -0,0 +1,21 @@
|
||||
I put together the sample configuration files in this directory in hopes
|
||||
that it would help folks see some of the possibilities of the
|
||||
configuration file format. Each of the files are syntatically correct,
|
||||
but have never actually been used.
|
||||
|
||||
Each file is basically built upon the previous...theoretically, if not
|
||||
actually. Hopefully they'll help show some of the cool things you can
|
||||
do with the configuration file and help those trying to figure out how
|
||||
they should even start.
|
||||
|
||||
simple.cf - A very simple, one console config file
|
||||
|
||||
basic.cf - A config with a couple consoles, mostly using defaults
|
||||
|
||||
average.cf - A config for many consoles, using breaks, user lists,
|
||||
etc...bascially customizing each area
|
||||
|
||||
average-distributed.cf - Taking average.cf to multiple conserver
|
||||
hosts with overrides on those hosts
|
||||
|
||||
Bryan Stansell
|
109
conserver.cf/samples/average-distributed.cf
Normal file
109
conserver.cf/samples/average-distributed.cf
Normal file
@ -0,0 +1,109 @@
|
||||
#
|
||||
# I took the average.cf file and expanded it to use a distributed
|
||||
# conserver setup...two conserver hosts (conserver1 and conserver2), but
|
||||
# the basic philosophy would hold for many more console and/or conserver
|
||||
# hosts.
|
||||
#
|
||||
|
||||
# ------ define a user group ------
|
||||
group sysadmin {
|
||||
users bryan, todd, dave;
|
||||
}
|
||||
# helpers is everyone but the sysadmin group
|
||||
group helpers {
|
||||
users *, !sysadmin;
|
||||
}
|
||||
|
||||
|
||||
# ------ make sure breaks are the way we want --------
|
||||
break 1 { string "\z"; }
|
||||
break 2 { string "\r\d~\d^b"; delay 600; }
|
||||
break 3 { string "#."; }
|
||||
|
||||
|
||||
# ----- define some console types ------
|
||||
# yeah, just setting a break doesn't quite seem worth it, but perhaps,
|
||||
# some day, there will be more host-specific stuff.
|
||||
default sun-std { break 1; }
|
||||
default sun-alt { break 2; }
|
||||
default sun-lom { break 3; }
|
||||
|
||||
|
||||
# ------ defaults ------
|
||||
# we set a 'global' default so we can reuse the bits below. we're going
|
||||
# to set the '*' default, then define consoles, reset the '*' default,
|
||||
# define more consoles, etc.
|
||||
default global {
|
||||
logfile /var/consoles/&; # '&' is replaced with console name
|
||||
timestamp 1hab; # write timestamps
|
||||
rw sysadmin; # allow sysadmins full access
|
||||
ro helpers; # allow helpers to watch
|
||||
include sun-std;
|
||||
}
|
||||
|
||||
|
||||
# --------- define our terminal attributes ----------
|
||||
# simple tcp connections are "easy"
|
||||
default cisco { type host; portbase 2000; portinc 1; }
|
||||
default xyplex { type host; portbase 2000; portinc 100; }
|
||||
|
||||
# this is a cyclades card referenced with /dev/ttyC0 through /dev/ttyC31
|
||||
# (referenced as ports 1 through 32 in conserver.cf)
|
||||
# we set the various port calculation bits and pattern substitution to
|
||||
# come up with a generic definition
|
||||
default cyclades { type device; device /dev/ttyC&; baud 9600; parity none;
|
||||
devicesubst &=Pd; portbase -1; portinc 1; host unused; }
|
||||
|
||||
## this is a term server accessed with an ssh command
|
||||
# it too uses pattern substitution and such to get the job done
|
||||
default ciscossh { type exec; portbase 2000; portinc 1;
|
||||
exec /usr/local/bin/ssh -p P -l tsuser H;
|
||||
execsubst H=hs,P=Pd; }
|
||||
|
||||
|
||||
# ------- set the global default for the first conserver host -------
|
||||
# the consoles below (until the default is reset) are managed
|
||||
# by conserver1.conserver.com
|
||||
default * { include global; master conserver1.conserver.com; }
|
||||
|
||||
# ------- define the consoles on ts1.conserver.com --------
|
||||
default ts1.conserver.com { include cisco; host ts1.conserver.com; }
|
||||
console web1.conserver.com { include ts1.conserver.com; port 2; }
|
||||
console ns1.conserver.com { include ts1.conserver.com; port 10; }
|
||||
|
||||
# ------- define the consoles on ts2.conserver.com --------
|
||||
default ts2.conserver.com { include xyplex; host ts2.conserver.com; }
|
||||
console web2.conserver.com { include ts2.conserver.com; port 4; }
|
||||
console ns2.conserver.com { include ts2.conserver.com; port 22; }
|
||||
|
||||
# ------- set the global default for the second conserver host -------
|
||||
# the following consoles are managed by conserver2.conserver.com
|
||||
default * { include global; master conserver2.conserver.com; }
|
||||
|
||||
# ------- define the consoles on ts3.conserver.com --------
|
||||
default ts3.conserver.com { include ciscossh; host ts3.conserver.com; }
|
||||
console ftp1.conserver.com { include ts3.conserver.com; include sun-lom;
|
||||
port 7; }
|
||||
|
||||
# ------- set up the an access list to avoid the default -------
|
||||
# anything *not* matched here will fallback to the default access mode
|
||||
access * {
|
||||
trusted 127.0.0.1;
|
||||
allowed 10.0.0.0/8;
|
||||
}
|
||||
|
||||
# conserver2 has an extra leg that is trusted
|
||||
access conserver2.conserver.com { trusted 192.168.0.0/16; }
|
||||
|
||||
# ------- do some server configuration ---------
|
||||
# both conserver1.conserver.com and conserver2.conserver.com use the same
|
||||
# set of defaults
|
||||
config * {
|
||||
defaultaccess rejected;
|
||||
daemonmode on;
|
||||
logfile /var/log/conserver;
|
||||
}
|
||||
|
||||
# we're going to set the default access on conserver2 to allowed, because
|
||||
# it's in a higher-trust network
|
||||
config conserver2.conserver.com { defaultaccess allowed; }
|
91
conserver.cf/samples/average.cf
Normal file
91
conserver.cf/samples/average.cf
Normal file
@ -0,0 +1,91 @@
|
||||
#
|
||||
# This would be what i'd expect a more common configuration file would
|
||||
# look like. There are consoles attached to multiple devices, simple
|
||||
# access lists, etc.
|
||||
#
|
||||
|
||||
# ------ define a user group ------
|
||||
group sysadmin {
|
||||
users bryan, todd, dave;
|
||||
}
|
||||
# helpers is everyone but the sysadmin group
|
||||
group helpers {
|
||||
users *, !sysadmin;
|
||||
}
|
||||
|
||||
|
||||
# ------ make sure breaks are the way we want --------
|
||||
break 1 { string "\z"; }
|
||||
break 2 { string "\r\d~\d^b"; delay 600; }
|
||||
break 3 { string "#."; }
|
||||
|
||||
|
||||
# ----- define some console types ------
|
||||
# yeah, just setting a break doesn't quite seem worth it, but perhaps,
|
||||
# some day, there will be more host-specific stuff.
|
||||
default sun-std { break 1; }
|
||||
default sun-alt { break 2; }
|
||||
default sun-lom { break 3; }
|
||||
|
||||
|
||||
# ------ defaults ------
|
||||
# now for some generic console defaults so that we don't have to
|
||||
# duplicate them for each console.
|
||||
default * {
|
||||
logfile /var/consoles/&; # '&' is replaced with console name
|
||||
timestamp 1hab; # write timestamps
|
||||
rw sysadmin; # allow sysadmins full access
|
||||
ro helpers; # allow helpers to watch
|
||||
master localhost;
|
||||
include sun-std;
|
||||
}
|
||||
|
||||
|
||||
# --------- define our terminal attributes ----------
|
||||
# simple tcp connections are "easy"
|
||||
default cisco { type host; portbase 2000; portinc 1; }
|
||||
default xyplex { type host; portbase 2000; portinc 100; }
|
||||
|
||||
# this is a cyclades card referenced with /dev/ttyC0 through /dev/ttyC31
|
||||
# (referenced as ports 1 through 32 in conserver.cf)
|
||||
# we set the various port calculation bits and pattern substitution to
|
||||
# come up with a generic definition
|
||||
default cyclades { type device; device /dev/ttyC&; baud 9600; parity none;
|
||||
devicesubst &=Pd; portbase -1; portinc 1; host unused; }
|
||||
|
||||
## this is a term server accessed with an ssh command
|
||||
# it too uses pattern substitution and such to get the job done
|
||||
default ciscossh { type exec; portbase 2000; portinc 1;
|
||||
exec /usr/local/bin/ssh -p P -l tsuser H;
|
||||
execsubst H=hs,P=Pd; }
|
||||
|
||||
|
||||
# ------- define the consoles on ts1.conserver.com --------
|
||||
default ts1.conserver.com { include cisco; host ts1.conserver.com; }
|
||||
console web1.conserver.com { include ts1.conserver.com; port 2; }
|
||||
console ns1.conserver.com { include ts1.conserver.com; port 10; }
|
||||
|
||||
# ------- define the consoles on ts2.conserver.com --------
|
||||
default ts2.conserver.com { include xyplex; host ts2.conserver.com; }
|
||||
console web2.conserver.com { include ts2.conserver.com; port 4; }
|
||||
console ns2.conserver.com { include ts2.conserver.com; port 22; }
|
||||
|
||||
# ------- define the consoles on ts3.conserver.com --------
|
||||
default ts3.conserver.com { include ciscossh; host ts3.conserver.com; }
|
||||
console ftp1.conserver.com { include ts3.conserver.com; include sun-lom;
|
||||
port 7; }
|
||||
|
||||
|
||||
# ------- set up the an access list to avoid the default -------
|
||||
# anything *not* matched here will fallback to the default access mode
|
||||
access * {
|
||||
trusted 127.0.0.1;
|
||||
allowed 10.0.0.0/8;
|
||||
}
|
||||
|
||||
# ------- do some server configuration ---------
|
||||
config * {
|
||||
defaultaccess rejected;
|
||||
daemonmode on;
|
||||
logfile /var/log/conserver;
|
||||
}
|
28
conserver.cf/samples/basic.cf
Normal file
28
conserver.cf/samples/basic.cf
Normal file
@ -0,0 +1,28 @@
|
||||
#
|
||||
# This is a fairly basic configuration file that interacts with one
|
||||
# terminal server.
|
||||
#
|
||||
|
||||
# first, we're going to set some generic console defaults so that we
|
||||
# don't have to duplicate them for each console.
|
||||
default * {
|
||||
logfile /var/consoles/&; # '&' is replaced with console name
|
||||
timestamp 1hab; # write timestamps
|
||||
rw *; # allow all users
|
||||
master localhost;
|
||||
type host;
|
||||
host ts1.conserver.com; # consoles on ts1.conserver.co
|
||||
portbase 2000; # port numbers start at 2001 and
|
||||
portinc 1; # go up by 1 (port #1 == 2001, etc)
|
||||
}
|
||||
|
||||
# define two consoles on the terminal server
|
||||
console web1.conserver.com { port 2; } # calculates to tcp port 2002
|
||||
console ns1.conserver.com { port 10; } # calculates to tcp port 2010
|
||||
|
||||
# set up the an access list to avoid the default
|
||||
# anything *not* matched here will fallback to the default access (-a)
|
||||
# mode
|
||||
access * {
|
||||
trusted 127.0.0.1;
|
||||
}
|
11
conserver.cf/samples/simple.cf
Normal file
11
conserver.cf/samples/simple.cf
Normal file
@ -0,0 +1,11 @@
|
||||
#
|
||||
# I believe this is the smallest configuration file that is also fully
|
||||
# functional. You have to be happy with the default access type (-a)
|
||||
# as well as the default access list that gets used.
|
||||
#
|
||||
|
||||
console simple {
|
||||
master localhost;
|
||||
type exec;
|
||||
rw *;
|
||||
}
|
@ -9,6 +9,7 @@
|
||||
<META name="author" content=
|
||||
"Bryan Stansell <bryan@conserver.com>">
|
||||
<LINK rel="SHORTCUT ICON" href="conserver.ico">
|
||||
<LINK rel="icon" href="conserver.ico">
|
||||
|
||||
<TITLE>Conserver</TITLE>
|
||||
|
||||
@ -55,11 +56,11 @@
|
||||
<INPUT type="HIDDEN" name="method" value="and"> <INPUT
|
||||
type="HIDDEN" name="format" value="builtin-long">
|
||||
<INPUT type="HIDDEN" name="sort" value="score"> <INPUT
|
||||
type="HIDDEN" name="config" value="htdig"> <INPUT type=
|
||||
"HIDDEN" name="restrict" value=""> <INPUT type="HIDDEN"
|
||||
name="exclude" value=""> <INPUT type="TEXT" size="20"
|
||||
name="words" value=""> <INPUT type="SUBMIT" value=
|
||||
"Search">
|
||||
type="HIDDEN" name="config" value="conserver.com">
|
||||
<INPUT type="HIDDEN" name="restrict" value=""> <INPUT
|
||||
type="HIDDEN" name="exclude" value=""> <INPUT type=
|
||||
"TEXT" size="20" name="words" value=""> <INPUT type=
|
||||
"SUBMIT" value="Search">
|
||||
</FORM>
|
||||
</TD>
|
||||
</TR>
|
||||
@ -159,35 +160,32 @@
|
||||
the website. Next, there's Kevin Braunsdorf's version at
|
||||
<A href=
|
||||
"ftp://ftp.physics.purdue.edu/pub/pundits/">ftp://ftp.physics.purdue.edu/pub/pundits/</A>.
|
||||
Kevin is semi-actively working on his thread. Doesn't
|
||||
look like any new versions have been out since August
|
||||
It doesn't look like Kevin is working on his thread ony
|
||||
more either. No new versions have been out since August
|
||||
2000 (version 8.5), but maybe this info will be out of
|
||||
date by the time you read this. Lastly, the conserver.com
|
||||
version is based on Kevin's "5.21-Beta" distribution, but
|
||||
since <B>HEAVILY</B> modified and enhanced (more details
|
||||
in the "Origin" section above).</P>
|
||||
date by the time you read this (I last checked Feb 10,
|
||||
2004). Lastly, the conserver.com version is based on
|
||||
Kevin's "5.21-Beta" distribution, but since
|
||||
<B>HEAVILY</B> modified and enhanced (more details in the
|
||||
"Origin" section above).</P>
|
||||
|
||||
<P>If I were looking for a conserver package I would
|
||||
either use Kevin's latest distribution or the
|
||||
conserver.com distribution. Which one? Well, obviously
|
||||
I'm biased and believe the conserver.com distribution
|
||||
should be your choice, but Kevin's does have UPS (serial
|
||||
port line toggling bits) that the conserver.com version
|
||||
doesn't have. What does the conserver.com distribution
|
||||
have? Well, in reality, too many things to list. You'll
|
||||
have to look at the <A href="CHANGES">CHANGES</A> file
|
||||
and see the enhancements, bug fixes, and general
|
||||
development since the original. Don't let the version
|
||||
numbers fool you - you'll have to compare and contrast
|
||||
for yourself.</P>
|
||||
definitely use the conserver.com distribution. Why? It's
|
||||
actively maintained, has many more features than the
|
||||
other versions (see <A href="CHANGES">CHANGES</A> for a
|
||||
semi-scary history), and has an active user community.
|
||||
Kevin's version does have UPS support (basic serial port
|
||||
line toggling bits) which is missing in the conserver.com
|
||||
version, but no one has asked me for it, so does anyone
|
||||
actually need it?</P>
|
||||
|
||||
<H3>Downloading</H3>
|
||||
|
||||
<P>The current version, released on Nov 20, 2003, is <A
|
||||
href="8.0.7.tar.gz">8.0.7.tar.gz</A>. You can get it via
|
||||
<P>The current version, released on Mar 22, 2004, is <A
|
||||
href="8.1.3.tar.gz">8.1.3.tar.gz</A>. You can get it via
|
||||
<A href=
|
||||
"ftp://ftp.conserver.com/conserver/8.0.7.tar.gz">FTP</A>
|
||||
or <A href="8.0.7.tar.gz">HTTP</A>. See the <A href=
|
||||
"ftp://ftp.conserver.com/conserver/8.1.3.tar.gz">FTP</A>
|
||||
or <A href="8.1.3.tar.gz">HTTP</A>. See the <A href=
|
||||
"CHANGES">CHANGES</A> file for information on the latest
|
||||
updates.</P>
|
||||
|
||||
@ -208,6 +206,11 @@
|
||||
<P>Check the <A href="INSTALL">INSTALL</A> file for
|
||||
instructions.</P>
|
||||
|
||||
<H3>Online Documentation</H3>
|
||||
|
||||
<P>I've put a small set of documentation <A href=
|
||||
"docs/">here</A>. I'm hoping to expand it over time.</P>
|
||||
|
||||
<H3>Systems Tested</H3>
|
||||
|
||||
<P>Here's a list of systems that I've been told can
|
||||
|
@ -6,7 +6,8 @@ exec_prefix = @exec_prefix@
|
||||
sbindir = @sbindir@
|
||||
sysconfdir = @sysconfdir@
|
||||
mandir = @mandir@
|
||||
exampledir = $(prefix)/share/examples/conserver
|
||||
datadir = @datadir@
|
||||
exampledir = $(datadir)/examples/conserver
|
||||
|
||||
### Installation programs and flags
|
||||
INSTALL = @INSTALL@
|
||||
@ -29,14 +30,17 @@ LIBS = @LIBS@ @CONSLIBS@
|
||||
CONSERVER_OBJS = access.o client.o consent.o group.o main.o master.o \
|
||||
readcfg.o fallback.o cutil.o
|
||||
CONSERVER_HDRS = ../config.h $(top_srcdir)/compat.h $(srcdir)/access.h \
|
||||
$(srcdir)/client.h $(srcdir)/consent.h $(srcdir)/group.h \
|
||||
$(srcdir)/main.h $(srcdir)/master.h $(srcdir)/readcfg.h \
|
||||
$(srcdir)/util.h
|
||||
$(srcdir)/client.h $(srcdir)/consent.h $(srcdir)/cutil.h \
|
||||
$(srcdir)/group.h $(srcdir)/main.h $(srcdir)/master.h \
|
||||
$(srcdir)/readcfg.h $(srcdir)/version.h
|
||||
|
||||
ALL = conserver convert
|
||||
|
||||
|
||||
all: $(ALL)
|
||||
|
||||
$(CONSERVER_OBJS): $(CONSERVER_HDRS)
|
||||
|
||||
conserver: $(CONSERVER_OBJS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o conserver $(CONSERVER_OBJS) $(LIBS)
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: client.c,v 5.76 2003/11/20 13:56:38 bryan Exp $
|
||||
* $Id: client.c,v 5.81 2004/03/20 14:40:40 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -97,15 +97,15 @@ FindWrite(pCE)
|
||||
*/
|
||||
void
|
||||
#if PROTOTYPES
|
||||
Replay(CONSFILE *fdLog, CONSFILE *fdOut, int iBack)
|
||||
Replay(CONSENT *pCE, CONSFILE *fdOut, int iBack)
|
||||
#else
|
||||
Replay(fdLog, fdOut, iBack)
|
||||
CONSFILE *fdLog;
|
||||
Replay(pCE, fdOut, iBack)
|
||||
CONSENT *pCE;
|
||||
CONSFILE *fdOut;
|
||||
int iBack;
|
||||
#endif
|
||||
{
|
||||
|
||||
CONSFILE *fdLog = (CONSFILE *)0;
|
||||
off_t file_pos;
|
||||
off_t buf_pos;
|
||||
char *buf;
|
||||
@ -130,7 +130,16 @@ Replay(fdLog, fdOut, iBack)
|
||||
unsigned long dmallocMarkReplay = 0;
|
||||
#endif
|
||||
|
||||
if ((CONSFILE *)0 == fdLog) {
|
||||
if (pCE != (CONSENT *)0) {
|
||||
fdLog = pCE->fdlog;
|
||||
|
||||
/* no logfile and down and logfile defined? try and open it */
|
||||
if (fdLog == (CONSFILE *)0 && !pCE->fup &&
|
||||
pCE->logfile != (char *)0)
|
||||
fdLog = FileOpen(pCE->logfile, O_RDONLY, 0644);
|
||||
}
|
||||
|
||||
if (fdLog == (CONSFILE *)0) {
|
||||
FileWrite(fdOut, FLAGFALSE, "[no log file on this console]\r\n",
|
||||
-1);
|
||||
return;
|
||||
@ -179,17 +188,9 @@ Replay(fdLog, fdOut, iBack)
|
||||
* the rest (as we work our way back in the file) should be
|
||||
*/
|
||||
buf_pos = (file_pos / BUFSIZ) * BUFSIZ;
|
||||
#if defined(SEEK_SET)
|
||||
/* PTX and maybe other Posix systems
|
||||
*/
|
||||
if (FileSeek(fdLog, buf_pos, SEEK_SET) < 0) {
|
||||
goto common_exit;
|
||||
}
|
||||
#else
|
||||
if (FileSeek(fdLog, buf_pos, L_SET) < 0) {
|
||||
goto common_exit;
|
||||
}
|
||||
#endif
|
||||
if ((r = FileRead(fdLog, buf, BUFSIZ)) < 0) {
|
||||
goto common_exit;
|
||||
}
|
||||
@ -339,6 +340,10 @@ Replay(fdLog, fdOut, iBack)
|
||||
|
||||
common_exit:
|
||||
|
||||
/* if we opened the logfile, close it */
|
||||
if (fdLog != pCE->fdlog)
|
||||
FileClose(&fdLog);
|
||||
|
||||
if ((struct lines *)0 != lines) {
|
||||
for (i = 0; i < n_lines; i++) {
|
||||
DestroyString(lines[i].mark_end);
|
||||
@ -362,8 +367,7 @@ Replay(fdLog, fdOut, iBack)
|
||||
*/
|
||||
#define WHEN_SPY 0x01
|
||||
#define WHEN_ATTACH 0x02
|
||||
#define WHEN_VT100 0x04
|
||||
#define WHEN_EXPERT 0x08 /* ZZZ no way to set his yet */
|
||||
#define WHEN_EXPERT 0x04 /* ZZZ no way to set his yet */
|
||||
#define WHEN_ALWAYS 0x40
|
||||
|
||||
#define HALFLINE 40
|
||||
@ -375,6 +379,7 @@ typedef struct HLnode {
|
||||
|
||||
static HELP aHLTable[] = {
|
||||
{WHEN_ALWAYS, ". disconnect"},
|
||||
{WHEN_ALWAYS, "; move to another console"},
|
||||
{WHEN_ALWAYS, "a attach read/write"},
|
||||
{WHEN_ALWAYS, "b send broadcast message"},
|
||||
{WHEN_ATTACH, "c toggle flow control"},
|
||||
@ -397,16 +402,13 @@ static HELP aHLTable[] = {
|
||||
{WHEN_ALWAYS, "w who is on this console"},
|
||||
{WHEN_ALWAYS, "x show console baud info"},
|
||||
{WHEN_ALWAYS, "z suspend the connection"},
|
||||
{WHEN_ALWAYS, "<cr> ignore/abort command"},
|
||||
{WHEN_ATTACH, "| attach local command"},
|
||||
{WHEN_ALWAYS, "? print this message"},
|
||||
{WHEN_ALWAYS, "<cr> ignore/abort command"},
|
||||
{WHEN_ALWAYS, "^R replay the last line"},
|
||||
{WHEN_ATTACH, "\\ooo send character by octal code"},
|
||||
{WHEN_EXPERT, "^I toggle tab expansion"},
|
||||
{WHEN_EXPERT, "+(-) do (not) drop line"},
|
||||
{WHEN_VT100, "PF1 print this message"},
|
||||
{WHEN_VT100, "PF2 disconnect"},
|
||||
{WHEN_VT100, "PF3 replay the last 20 lines"},
|
||||
{WHEN_VT100, "PF4 spy read only"}
|
||||
};
|
||||
|
||||
/* list the commands we know for the user (ksb)
|
||||
@ -435,9 +437,6 @@ HelpUser(pCL)
|
||||
} else {
|
||||
FileWrite(pCL->fd, FLAGTRUE, acH2, sizeof(acH2) - 1);
|
||||
}
|
||||
if ('\033' == pCL->ic[0] && 'O' == pCL->ic[1]) {
|
||||
iCmp |= WHEN_VT100;
|
||||
}
|
||||
|
||||
BuildString((char *)0, acLine);
|
||||
for (i = 0; i < sizeof(aHLTable) / sizeof(HELP); ++i) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: client.h,v 5.33 2003/10/10 10:28:49 bryan Exp $
|
||||
* $Id: client.h,v 5.36 2003/12/25 19:22:00 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -46,7 +46,9 @@ typedef enum clientState {
|
||||
S_IDENT, /* probational connection (who is this) */
|
||||
S_PASSWD, /* still needs a passwd to connect */
|
||||
S_QUOTE, /* send any character we can spell */
|
||||
S_BCAST /* send a broadcast message to all clients */
|
||||
S_BCAST, /* send a broadcast message to all clients */
|
||||
S_CWAIT, /* wait for client */
|
||||
S_CEXEC /* client execing a program */
|
||||
} CLIENTSTATE;
|
||||
|
||||
typedef struct client { /* Connection Information: */
|
||||
@ -82,7 +84,7 @@ typedef struct client { /* Connection Information: */
|
||||
cnct_port; /* where from */
|
||||
} CONSCLIENT;
|
||||
|
||||
extern void Replay PARAMS((CONSFILE *, CONSFILE *, int));
|
||||
extern void Replay PARAMS((CONSENT *, CONSFILE *, int));
|
||||
extern void HelpUser PARAMS((CONSCLIENT *));
|
||||
extern void FindWrite PARAMS((CONSENT *));
|
||||
extern int ClientAccessOk PARAMS((CONSCLIENT *));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: consent.c,v 5.131 2003/11/20 13:56:38 bryan Exp $
|
||||
* $Id: consent.c,v 5.137 2004/02/20 14:58:13 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -236,6 +236,23 @@ TtyDev(pCE)
|
||||
ConsDown(pCE, FLAGTRUE, FLAGTRUE);
|
||||
return -1;
|
||||
}
|
||||
if (fDebug >= 2) {
|
||||
int i;
|
||||
Debug(2, "TtyDev(): [%s] termp.c_iflag=%lu", pCE->server,
|
||||
(unsigned long)termp.c_iflag);
|
||||
Debug(2, "TtyDev(): [%s] termp.c_oflag=%lu", pCE->server,
|
||||
(unsigned long)termp.c_oflag);
|
||||
Debug(2, "TtyDev(): [%s] termp.c_cflag=%lu", pCE->server,
|
||||
(unsigned long)termp.c_cflag);
|
||||
Debug(2, "TtyDev(): [%s] termp.c_lflag=%lu", pCE->server,
|
||||
(unsigned long)termp.c_lflag);
|
||||
#if defined(NCCS)
|
||||
for (i = 0; i < NCCS; i++) {
|
||||
Debug(2, "TtyDev(): [%s] termp.c_cc[%d]=%lu", pCE->server, i,
|
||||
(unsigned long)termp.c_cc[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
# if HAVE_STROPTS_H
|
||||
/*
|
||||
* eat all the streams modules upto and including ttcompat
|
||||
@ -261,12 +278,12 @@ StopInit(pCE)
|
||||
|
||||
if (pCE->initpid != 0) {
|
||||
kill(pCE->initpid, SIGHUP);
|
||||
pCE->initpid = 0;
|
||||
Verbose("[%s] initcmd terminated: pid %lu", pCE->server,
|
||||
(unsigned long)pCE->initpid);
|
||||
TagLogfileAct(pCE, "initcmd terminated");
|
||||
CONDDEBUG((1, "StopInit(): sending initcmd pid %lu signal %d",
|
||||
(unsigned long)pCE->initpid, SIGHUP));
|
||||
Msg("[%s] initcmd terminated: pid %lu", pCE->server,
|
||||
(unsigned long)pCE->initpid);
|
||||
TagLogfileAct(pCE, "initcmd terminated");
|
||||
pCE->initpid = 0;
|
||||
}
|
||||
|
||||
if (pCE->initfile != (CONSFILE *)0) {
|
||||
@ -359,8 +376,8 @@ StartInit(pCE)
|
||||
pCE->initpid = 0;
|
||||
return;
|
||||
}
|
||||
Verbose("[%s] initcmd started: pid %lu", pCE->server,
|
||||
(unsigned long)pCE->initpid);
|
||||
Msg("[%s] initcmd started: pid %lu", pCE->server,
|
||||
(unsigned long)pCE->initpid);
|
||||
TagLogfileAct(pCE, "initcmd started");
|
||||
FD_SET(pin[0], &rinit);
|
||||
if (maxfd < pin[0] + 1)
|
||||
@ -691,7 +708,7 @@ ConsInit(pCE)
|
||||
TagLogfile(pCE, "Console up");
|
||||
|
||||
switch (pCE->type) {
|
||||
case UNKNOWN: /* shut up gcc */
|
||||
case UNKNOWNTYPE: /* shut up gcc */
|
||||
break;
|
||||
case EXEC:
|
||||
if ((cofile =
|
||||
@ -741,7 +758,7 @@ ConsInit(pCE)
|
||||
hp->h_length);
|
||||
#endif
|
||||
port.sin_family = hp->h_addrtype;
|
||||
port.sin_port = htons(pCE->port);
|
||||
port.sin_port = htons(pCE->netport);
|
||||
|
||||
if ((cofile = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
||||
Error
|
||||
@ -826,14 +843,14 @@ ConsInit(pCE)
|
||||
}
|
||||
|
||||
switch (pCE->type) {
|
||||
case UNKNOWN: /* shut up gcc */
|
||||
case UNKNOWNTYPE: /* shut up gcc */
|
||||
break;
|
||||
case EXEC:
|
||||
Verbose("[%s] pid %lu on %s", pCE->server, pCE->ipid,
|
||||
pCE->execSlave);
|
||||
break;
|
||||
case HOST:
|
||||
Verbose("[%s] port %hu on %s", pCE->server, pCE->port,
|
||||
Verbose("[%s] port %hu on %s", pCE->server, pCE->netport,
|
||||
pCE->host);
|
||||
break;
|
||||
case DEVICE:
|
||||
@ -842,7 +859,13 @@ ConsInit(pCE)
|
||||
break;
|
||||
}
|
||||
|
||||
FD_SET(cofile, &rinit);
|
||||
/* if we're waiting for connect() to finish, watch the
|
||||
* write bit, otherwise watch for the read bit
|
||||
*/
|
||||
if (pCE->ioState == INCONNECT)
|
||||
FD_SET(cofile, &winit);
|
||||
else
|
||||
FD_SET(cofile, &rinit);
|
||||
if (maxfd < cofile + 1)
|
||||
maxfd = cofile + 1;
|
||||
|
||||
@ -851,9 +874,9 @@ ConsInit(pCE)
|
||||
if (pCE->ioState == ISNORMAL) {
|
||||
pCE->lastWrite = tyme;
|
||||
if (pCE->idletimeout != (time_t)0 &&
|
||||
(timers[T_IDLE] == (time_t)0 ||
|
||||
timers[T_IDLE] > pCE->lastWrite + pCE->idletimeout))
|
||||
timers[T_IDLE] = pCE->lastWrite + pCE->idletimeout;
|
||||
(timers[T_CIDLE] == (time_t)0 ||
|
||||
timers[T_CIDLE] > pCE->lastWrite + pCE->idletimeout))
|
||||
timers[T_CIDLE] = pCE->lastWrite + pCE->idletimeout;
|
||||
}
|
||||
|
||||
/* If we have marks, adjust the next one so that it's in the future */
|
||||
@ -871,7 +894,7 @@ ConsInit(pCE)
|
||||
if (pCE->ioState == ISNORMAL)
|
||||
Msg("[%s] console up", pCE->server);
|
||||
else
|
||||
Msg("[%s] console inititalizing", pCE->server);
|
||||
Msg("[%s] console initializing", pCE->server);
|
||||
pCE->downHard = FLAGFALSE;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: consent.h,v 5.52 2003/11/15 20:00:08 bryan Exp $
|
||||
* $Id: consent.h,v 5.56 2004/02/20 14:58:14 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -52,7 +52,7 @@ typedef struct parity { /* a parity bits table */
|
||||
} PARITY;
|
||||
|
||||
typedef enum consType {
|
||||
UNKNOWN = 0,
|
||||
UNKNOWNTYPE = 0,
|
||||
DEVICE,
|
||||
EXEC,
|
||||
HOST
|
||||
@ -92,9 +92,11 @@ typedef struct consent { /* console information */
|
||||
#endif
|
||||
/* type == HOST */
|
||||
char *host; /* hostname */
|
||||
unsigned short port; /* port number socket = portbase + */
|
||||
unsigned short portbase; /* port base portinc * port */
|
||||
unsigned short netport; /* final port | netport = portbase + */
|
||||
unsigned short port; /* port number | portinc * port */
|
||||
unsigned short portbase; /* port base */
|
||||
unsigned short portinc; /* port increment */
|
||||
unsigned short raw; /* raw or telnet protocol? */
|
||||
/* type == EXEC */
|
||||
char *exec; /* exec command */
|
||||
char *execsubst; /* exec substitution pattern */
|
||||
@ -102,7 +104,9 @@ typedef struct consent { /* console information */
|
||||
char *master; /* master hostname */
|
||||
unsigned short breakNum; /* break type [1-9] */
|
||||
char *logfile; /* logfile */
|
||||
off_t logfilemax; /* size limit for rolling logfile */
|
||||
char *initcmd; /* initcmd command */
|
||||
char *initsubst; /* initcmd substitution pattern */
|
||||
char *motd; /* motd */
|
||||
time_t idletimeout; /* idle timeout */
|
||||
char *idlestring; /* string to print when idle */
|
||||
|
@ -1,6 +1,6 @@
|
||||
.\" @(#)conserver.8 01/06/91 OSU CIS; Thomas A. Fine
|
||||
.\" $Id: conserver.man,v 1.40 2003/11/10 15:37:24 bryan Exp $
|
||||
.TH CONSERVER 8 "2003/11/10" "conserver-8.0.7" "conserver"
|
||||
.\" $Id: conserver.man,v 1.43 2004/03/23 01:02:29 bryan Exp $
|
||||
.TH CONSERVER 8 "2004/03/23" "conserver-8.1.3" "conserver"
|
||||
.SH NAME
|
||||
conserver \- console server daemon
|
||||
.SH SYNOPSIS
|
||||
@ -324,6 +324,37 @@ connect to remote consoles will result in an informative message to the user.
|
||||
.B \-S
|
||||
Do not run the server, just perform a syntax check of configuration file and
|
||||
exit with a non-zero value if there is an error.
|
||||
Using more than one
|
||||
.B \-S
|
||||
will cause conserver to output various information about each console in 5
|
||||
colon-separated fields, enclosed in curly-braces.
|
||||
The philosophy behind the output is to provide information to allow external
|
||||
detection of multiple consoles access the same physical port.
|
||||
Since this is
|
||||
.I highly
|
||||
environment-specific, conserver cannot do the check internally.
|
||||
.RS
|
||||
.TP 9
|
||||
.I name
|
||||
The name of the console.
|
||||
.TP
|
||||
.I master
|
||||
The hostname of the master conserver host for the console.
|
||||
.TP
|
||||
.I aliases
|
||||
The console aliases in a comma-separated list.
|
||||
.TP
|
||||
.I type
|
||||
The type of console.
|
||||
Values will be a `/' for a local device, `|' for
|
||||
a command, or `!' for a remote port.
|
||||
.TP
|
||||
.I details
|
||||
Multiple values are comma-separated and depend on the type of the console.
|
||||
Local devices will have the values of the device file and baud rate/parity.
|
||||
Commands will have string to invoke.
|
||||
Remote ports will have the values of the remote hostname and port number.
|
||||
.RE
|
||||
.TP
|
||||
.B \-u
|
||||
Send unloved console output to
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: cutil.c,v 1.107 2003/11/20 13:59:55 bryan Exp $
|
||||
* $Id: cutil.c,v 1.116 2004/03/19 05:23:21 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -238,6 +238,35 @@ BuildStringN(str, n, msg)
|
||||
return msg->string;
|
||||
}
|
||||
|
||||
void *
|
||||
#if PROTOTYPES
|
||||
MemMove(void *dest, void *src, size_t n)
|
||||
#else
|
||||
MemMove(void *dest, void *src, size_t n)
|
||||
void *dest;
|
||||
void *src;
|
||||
size_t n;
|
||||
#endif
|
||||
{
|
||||
#if HAVE_MEMMOVE
|
||||
return memmove(dest, src, n);
|
||||
#else
|
||||
char *s = src;
|
||||
char *d = dest;
|
||||
|
||||
if (s < d) {
|
||||
/* Moving from low mem to hi mem; start at end. */
|
||||
for (s += n, d += n; n > 0; --n)
|
||||
*--d = *--s;
|
||||
} else if (s != d) {
|
||||
/* Moving from hi mem to low mem; start at beginning. */
|
||||
for (; n > 0; --n)
|
||||
*d++ = *s++;
|
||||
}
|
||||
return dest;
|
||||
#endif
|
||||
}
|
||||
|
||||
char *
|
||||
#if PROTOTYPES
|
||||
ShiftString(STRING *msg, int n)
|
||||
@ -250,17 +279,8 @@ ShiftString(msg, n)
|
||||
if (msg == (STRING *)0 || n <= 0 || n > msg->used - 1)
|
||||
return (char *)0;
|
||||
|
||||
#if HAVE_MEMMOVE
|
||||
memmove(msg->string, msg->string + n, msg->used - n);
|
||||
#else
|
||||
{
|
||||
char *s, *e;
|
||||
int len;
|
||||
for (s = msg->string, e = s + n, len = msg->used - n; len > 0;
|
||||
len--)
|
||||
*s++ = *e++;
|
||||
}
|
||||
#endif
|
||||
MemMove(msg->string, msg->string + n, msg->used - n);
|
||||
|
||||
msg->used -= n;
|
||||
return msg->string;
|
||||
}
|
||||
@ -730,6 +750,27 @@ FileOpenFD(fd, type)
|
||||
cfp->ssl = (SSL *)0;
|
||||
cfp->waitForRead = cfp->waitForWrite = FLAGFALSE;
|
||||
#endif
|
||||
#if DEBUG_CONSFILE_IO
|
||||
{
|
||||
char buf[1024];
|
||||
sprintf(buf, "CONSFILE-%s-%lu-%d.w", progname,
|
||||
(unsigned long)thepid, fd);
|
||||
if ((cfp->debugwfd =
|
||||
open(buf, O_WRONLY | O_CREAT | O_APPEND, 0644)) != -1) {
|
||||
sprintf(buf, "[---- STARTED - %s ----]\n",
|
||||
StrTime((time_t *)0));
|
||||
write(cfp->debugwfd, buf, strlen(buf));
|
||||
}
|
||||
sprintf(buf, "CONSFILE-%s-%lu-%d.r", progname,
|
||||
(unsigned long)thepid, fd);
|
||||
if ((cfp->debugrfd =
|
||||
open(buf, O_WRONLY | O_CREAT | O_APPEND, 0644)) != -1) {
|
||||
sprintf(buf, "[---- STARTED - %s ----]\n",
|
||||
StrTime((time_t *)0));
|
||||
write(cfp->debugrfd, buf, strlen(buf));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
CONDDEBUG((2, "FileOpenFD(): encapsulated fd %d type %d", fd, type));
|
||||
return cfp;
|
||||
@ -760,6 +801,27 @@ FileOpenPipe(fd, fdout)
|
||||
cfp->ssl = (SSL *)0;
|
||||
cfp->waitForRead = cfp->waitForWrite = FLAGFALSE;
|
||||
#endif
|
||||
#if DEBUG_CONSFILE_IO
|
||||
{
|
||||
char buf[1024];
|
||||
sprintf(buf, "CONSFILE-%s-%lu-%d.w", progname,
|
||||
(unsigned long)thepid, fdout);
|
||||
if ((cfp->debugwfd =
|
||||
open(buf, O_WRONLY | O_CREAT | O_APPEND, 0644)) != -1) {
|
||||
sprintf(buf, "[---- STARTED - %s ----]\n",
|
||||
StrTime((time_t *)0));
|
||||
write(cfp->debugwfd, buf, strlen(buf));
|
||||
}
|
||||
sprintf(buf, "CONSFILE-%s-%lu-%d.r", progname,
|
||||
(unsigned long)thepid, fd);
|
||||
if ((cfp->debugrfd =
|
||||
open(buf, O_WRONLY | O_CREAT | O_APPEND, 0644)) != -1) {
|
||||
sprintf(buf, "[---- STARTED - %s ----]\n",
|
||||
StrTime((time_t *)0));
|
||||
write(cfp->debugrfd, buf, strlen(buf));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
CONDDEBUG((2, "FileOpenPipe(): encapsulated pipe pair fd %d and fd %d",
|
||||
fd, fdout));
|
||||
@ -777,6 +839,9 @@ FileUnopen(cfp)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
if (cfp == (CONSFILE *)0)
|
||||
return 0;
|
||||
|
||||
switch (cfp->ftype) {
|
||||
case simpleFile:
|
||||
retval = cfp->fd;
|
||||
@ -798,6 +863,12 @@ FileUnopen(cfp)
|
||||
}
|
||||
CONDDEBUG((2, "FileUnopen(): unopened fd %d", cfp->fd));
|
||||
DestroyString(cfp->wbuf);
|
||||
#if DEBUG_CONSFILE_IO
|
||||
if (cfp->debugwfd != -1)
|
||||
close(cfp->debugwfd);
|
||||
if (cfp->debugrfd != -1)
|
||||
close(cfp->debugrfd);
|
||||
#endif
|
||||
free(cfp);
|
||||
|
||||
return retval;
|
||||
@ -833,6 +904,27 @@ FileOpen(path, flag, mode)
|
||||
cfp->ssl = (SSL *)0;
|
||||
cfp->waitForRead = cfp->waitForWrite = FLAGFALSE;
|
||||
#endif
|
||||
#if DEBUG_CONSFILE_IO
|
||||
{
|
||||
char buf[1024];
|
||||
sprintf(buf, "CONSFILE-%s-%lu-%d.w", progname,
|
||||
(unsigned long)thepid, fd);
|
||||
if ((cfp->debugwfd =
|
||||
open(buf, O_WRONLY | O_CREAT | O_APPEND, 0644)) != -1) {
|
||||
sprintf(buf, "[---- STARTED - %s ----]\n",
|
||||
StrTime((time_t *)0));
|
||||
write(cfp->debugwfd, buf, strlen(buf));
|
||||
}
|
||||
sprintf(buf, "CONSFILE-%s-%lu-%d.r", progname,
|
||||
(unsigned long)thepid, fd);
|
||||
if ((cfp->debugrfd =
|
||||
open(buf, O_WRONLY | O_CREAT | O_APPEND, 0644)) != -1) {
|
||||
sprintf(buf, "[---- STARTED - %s ----]\n",
|
||||
StrTime((time_t *)0));
|
||||
write(cfp->debugrfd, buf, strlen(buf));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
CONDDEBUG((2, "FileOpen(): opened `%s' as fd %d", path, fd));
|
||||
return cfp;
|
||||
@ -921,8 +1013,19 @@ FileClose(pcfp)
|
||||
break;
|
||||
}
|
||||
|
||||
CONDDEBUG((2, "FileClose(): closed fd %d", cfp->fd));
|
||||
if (cfp->ftype == simplePipe) {
|
||||
CONDDEBUG((2, "FileClose(): closed fd %d/%d", cfp->fd,
|
||||
cfp->fdout));
|
||||
} else {
|
||||
CONDDEBUG((2, "FileClose(): closed fd %d", cfp->fd));
|
||||
}
|
||||
DestroyString(cfp->wbuf);
|
||||
#if DEBUG_CONSFILE_IO
|
||||
if (cfp->debugwfd != -1)
|
||||
close(cfp->debugwfd);
|
||||
if (cfp->debugrfd != -1)
|
||||
close(cfp->debugrfd);
|
||||
#endif
|
||||
free(cfp);
|
||||
*pcfp = (CONSFILE *)0;
|
||||
|
||||
@ -964,6 +1067,10 @@ FileRead(cfp, buf, len)
|
||||
retval = -1;
|
||||
break;
|
||||
}
|
||||
#if DEBUG_CONSFILE_IO
|
||||
if (cfp->debugrfd != -1)
|
||||
write(cfp->debugrfd, buf, retval);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#if HAVE_OPENSSL
|
||||
@ -1002,6 +1109,10 @@ FileRead(cfp, buf, len)
|
||||
cfp->ftype = simpleSocket;
|
||||
break;
|
||||
}
|
||||
#if DEBUG_CONSFILE_IO
|
||||
if (cfp->debugrfd != -1)
|
||||
write(cfp->debugrfd, buf, retval);
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
@ -1075,9 +1186,23 @@ FileWrite(cfp, bufferonly, buf, len)
|
||||
tmpString->string, fdout));
|
||||
}
|
||||
}
|
||||
|
||||
/* save the data */
|
||||
if (len > 0 && buf != (char *)0)
|
||||
BuildStringN(buf, len, cfp->wbuf);
|
||||
if (len > 0 && buf != (char *)0) {
|
||||
if (cfp->quoteiac == FLAGTRUE) {
|
||||
int l, o;
|
||||
for (o = l = 0; l < len; l++) {
|
||||
if (buf[l] == (char)OB_IAC) {
|
||||
BuildStringN(buf + o, l + 1 - o, cfp->wbuf);
|
||||
BuildStringChar((char)OB_IAC, cfp->wbuf);
|
||||
o = l + 1;
|
||||
}
|
||||
}
|
||||
if (o < len)
|
||||
BuildStringN(buf + o, len - o, cfp->wbuf);
|
||||
} else
|
||||
BuildStringN(buf, len, cfp->wbuf);
|
||||
}
|
||||
|
||||
if (bufferonly == FLAGTRUE)
|
||||
return 0;
|
||||
@ -1108,12 +1233,29 @@ FileWrite(cfp, bufferonly, buf, len)
|
||||
break;
|
||||
}
|
||||
retval = -1;
|
||||
/* i believe, as of 8.0.8, we need to just ignore
|
||||
* this and actually produce the error message
|
||||
* below. perhaps we'll have a lot of extra
|
||||
* FileWrite() errors, perhaps not. things shouldn't
|
||||
* just close down and cause errors in normal cases,
|
||||
* right?!? -bryan
|
||||
* maybe not right now, actually. i'm going to check
|
||||
* the return code of FileWrite() on the "important"
|
||||
* things and let the others silently fail and have
|
||||
* the FileRead() catch problems - like it has been
|
||||
* doing. i really should be checking all the return
|
||||
* codes...and i'm sure i'll get there eventually.
|
||||
*/
|
||||
if (errno == EPIPE)
|
||||
break;
|
||||
Error("FileWrite(): fd %d: %s", fdout,
|
||||
strerror(errno));
|
||||
break;
|
||||
}
|
||||
#if DEBUG_CONSFILE_IO
|
||||
if (cfp->debugwfd != -1)
|
||||
write(cfp->debugwfd, buf, retval);
|
||||
#endif
|
||||
buf += retval;
|
||||
len -= retval;
|
||||
len_out += retval;
|
||||
@ -1158,6 +1300,10 @@ FileWrite(cfp, bufferonly, buf, len)
|
||||
}
|
||||
if (retval <= 0)
|
||||
break;
|
||||
#if DEBUG_CONSFILE_IO
|
||||
if (cfp->debugwfd != -1)
|
||||
write(cfp->debugwfd, buf, retval);
|
||||
#endif
|
||||
buf += retval;
|
||||
len -= retval;
|
||||
len_out += retval;
|
||||
@ -1348,6 +1494,8 @@ VWrite(cfp, bufferonly, str, fmt, ap)
|
||||
break;
|
||||
case 's':
|
||||
p = va_arg(ap, char *);
|
||||
if (p == (char *)0)
|
||||
p = "(null)";
|
||||
{
|
||||
int l = strlen(p);
|
||||
int c;
|
||||
@ -1739,6 +1887,71 @@ FileSetType(cfp, type)
|
||||
cfp->ftype = type;
|
||||
}
|
||||
|
||||
/* Sets the file quoting method */
|
||||
void
|
||||
#if PROTOTYPES
|
||||
FileSetQuoteIAC(CONSFILE *cfp, FLAG flag)
|
||||
#else
|
||||
FileSetQuoteIAC(cfp, flag)
|
||||
CONSFILE *cfp;
|
||||
FLAG flag;
|
||||
#endif
|
||||
{
|
||||
cfp->quoteiac = flag;
|
||||
}
|
||||
|
||||
FLAG
|
||||
#if PROTOTYPES
|
||||
FileSawQuoteSusp(CONSFILE *cfp)
|
||||
#else
|
||||
FileSawQuoteSusp(cfp)
|
||||
CONSFILE *cfp;
|
||||
#endif
|
||||
{
|
||||
FLAG r = cfp->sawiacsusp;
|
||||
cfp->sawiacsusp = FLAGFALSE;
|
||||
return r;
|
||||
}
|
||||
|
||||
FLAG
|
||||
#if PROTOTYPES
|
||||
FileSawQuoteExec(CONSFILE *cfp)
|
||||
#else
|
||||
FileSawQuoteExec(cfp)
|
||||
CONSFILE *cfp;
|
||||
#endif
|
||||
{
|
||||
FLAG r = cfp->sawiacexec;
|
||||
cfp->sawiacexec = FLAGFALSE;
|
||||
return r;
|
||||
}
|
||||
|
||||
FLAG
|
||||
#if PROTOTYPES
|
||||
FileSawQuoteAbrt(CONSFILE *cfp)
|
||||
#else
|
||||
FileSawQuoteAbrt(cfp)
|
||||
CONSFILE *cfp;
|
||||
#endif
|
||||
{
|
||||
FLAG r = cfp->sawiacabrt;
|
||||
cfp->sawiacabrt = FLAGFALSE;
|
||||
return r;
|
||||
}
|
||||
|
||||
FLAG
|
||||
#if PROTOTYPES
|
||||
FileSawQuoteGoto(CONSFILE *cfp)
|
||||
#else
|
||||
FileSawQuoteGoto(cfp)
|
||||
CONSFILE *cfp;
|
||||
#endif
|
||||
{
|
||||
FLAG r = cfp->sawiacgoto;
|
||||
cfp->sawiacgoto = FLAGFALSE;
|
||||
return r;
|
||||
}
|
||||
|
||||
#if HAVE_OPENSSL
|
||||
/* Get the SSL instance */
|
||||
SSL *
|
||||
@ -2070,3 +2283,108 @@ StrDup(msg)
|
||||
#endif
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *
|
||||
#if PROTOTYPES
|
||||
StringChar(STRING *msg, int offset, char c)
|
||||
#else
|
||||
StringChar(msg, offset, c)
|
||||
STRING *msg;
|
||||
int offset;
|
||||
char c;
|
||||
#endif
|
||||
{
|
||||
int o;
|
||||
|
||||
if (msg == (STRING *)0 || msg->used <= 1 || offset < 0 ||
|
||||
offset > msg->used)
|
||||
return (char *)0;
|
||||
|
||||
for (o = offset; o != msg->used; o++) {
|
||||
if (msg->string[o] == c)
|
||||
return &(msg->string[o]);
|
||||
}
|
||||
return (char *)0;
|
||||
}
|
||||
|
||||
/* this takes a buffer, and returns the number of characters to use,
|
||||
* which goes up to the first OB_IAC character sequence (that isn't
|
||||
* OB_IAC/OB_IAC). if it is an OB_IAC sequence, it sets the flag and
|
||||
* returns zero. if it's invalid args, we return -1.
|
||||
* so <0 == no data, 0 == check flags, >0 number of chars to use
|
||||
* this *WILL* modify the buffer (OB_IAC sequences get extracted/shrunk)
|
||||
*/
|
||||
int
|
||||
#if PROTOTYPES
|
||||
ParseIACBuf(CONSFILE *cfp, void *msg, int *len)
|
||||
#else
|
||||
ParseIACBuf(cfp, msg, len)
|
||||
CONSFILE *cfp;
|
||||
void *msg;
|
||||
int *len;
|
||||
#endif
|
||||
{
|
||||
int l = 0;
|
||||
unsigned char *b = msg;
|
||||
|
||||
if (*len <= 0)
|
||||
return -1;
|
||||
|
||||
if (cfp->quoteiac != FLAGTRUE)
|
||||
return *len;
|
||||
|
||||
/* split OB_IAC/char pair OR OB_IAC at start */
|
||||
if (cfp->sawiac == FLAGTRUE || b[0] == OB_IAC) {
|
||||
int i = 1;
|
||||
|
||||
if (cfp->sawiac == FLAGTRUE) {
|
||||
i = 0;
|
||||
cfp->sawiac = FLAGFALSE;
|
||||
}
|
||||
if (i == *len) { /* only thing is OB_IAC */
|
||||
cfp->sawiac = FLAGTRUE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (b[i] == OB_SUSP)
|
||||
cfp->sawiacsusp = FLAGTRUE;
|
||||
else if (b[i] == OB_EXEC)
|
||||
cfp->sawiacexec = FLAGTRUE;
|
||||
else if (b[i] == OB_ABRT)
|
||||
cfp->sawiacabrt = FLAGTRUE;
|
||||
else if (b[i] == OB_GOTO)
|
||||
cfp->sawiacgoto = FLAGTRUE;
|
||||
else {
|
||||
if (b[i] != OB_IAC)
|
||||
Error
|
||||
("ParseIACBuf(): fd %d: unrecognized quoted-OB_IAC char",
|
||||
cfp->fd, strerror(errno));
|
||||
l = 1;
|
||||
}
|
||||
*len = *len - i - 1 + l;
|
||||
MemMove(b, b + i + 1 - l, *len);
|
||||
if (l == 0)
|
||||
return 0;
|
||||
}
|
||||
for (; l < *len; l++) {
|
||||
if (b[l] == OB_IAC) {
|
||||
if (l + 1 == *len)
|
||||
return l;
|
||||
else if (b[l + 1] == OB_SUSP)
|
||||
return l;
|
||||
else if (b[l + 1] == OB_EXEC)
|
||||
return l;
|
||||
else if (b[l + 1] == OB_ABRT)
|
||||
return l;
|
||||
else {
|
||||
if (b[l + 1] != OB_IAC)
|
||||
Error
|
||||
("ParseIACBuf(): fd %d: unrecognized quoted-OB_IAC char",
|
||||
cfp->fd, strerror(errno));
|
||||
--(*len);
|
||||
MemMove(b + l, b + l + 1, *len - l);
|
||||
}
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: cutil.h,v 1.56 2003/11/10 20:38:25 bryan Exp $
|
||||
* $Id: cutil.h,v 1.61 2004/03/10 02:55:45 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -18,8 +18,11 @@
|
||||
|
||||
/* communication constants
|
||||
*/
|
||||
#define OB_IAC 0xff /* quote char */
|
||||
#define OB_EXEC 'E' /* exec a command on the client */
|
||||
#define OB_GOTO 'G' /* goto next console */
|
||||
#define OB_SUSP 'Z' /* suspended by server */
|
||||
#define OB_DROP '.' /* dropped by server */
|
||||
#define OB_ABRT '.' /* abort */
|
||||
|
||||
/* Struct to wrap information about a "file"...
|
||||
* This can be a socket, local file, whatever. We do this so
|
||||
@ -67,6 +70,12 @@ typedef struct consFile {
|
||||
int fd;
|
||||
int fdout; /* only used when a simplePipe */
|
||||
STRING *wbuf;
|
||||
FLAG quoteiac;
|
||||
FLAG sawiac;
|
||||
FLAG sawiacsusp;
|
||||
FLAG sawiacexec;
|
||||
FLAG sawiacabrt;
|
||||
FLAG sawiacgoto;
|
||||
#if HAVE_OPENSSL
|
||||
/* SSL stuff */
|
||||
SSL *ssl;
|
||||
@ -74,6 +83,10 @@ typedef struct consFile {
|
||||
FLAG waitForRead;
|
||||
#endif
|
||||
/* Add crypto stuff to suit */
|
||||
#if DEBUG_CONSFILE_IO
|
||||
int debugrfd;
|
||||
int debugwfd;
|
||||
#endif
|
||||
} CONSFILE;
|
||||
|
||||
extern int isMultiProc, fDebug, fVerbose, fErrorPrinted;
|
||||
@ -127,6 +140,11 @@ extern STRING *AllocString PARAMS((void));
|
||||
extern char *ReadLine PARAMS((FILE *, STRING *, int *));
|
||||
extern enum consFileType FileGetType PARAMS((CONSFILE *));
|
||||
extern void FileSetType PARAMS((CONSFILE *, enum consFileType));
|
||||
extern void FileSetQuoteIAC PARAMS((CONSFILE *, FLAG));
|
||||
extern FLAG FileSawQuoteSusp PARAMS((CONSFILE *));
|
||||
extern FLAG FileSawQuoteExec PARAMS((CONSFILE *));
|
||||
extern FLAG FileSawQuoteAbrt PARAMS((CONSFILE *));
|
||||
extern FLAG FileSawQuoteGoto PARAMS((CONSFILE *));
|
||||
extern void Bye PARAMS((int));
|
||||
extern void DestroyDataStructures PARAMS((void));
|
||||
extern int IsMe PARAMS((char *));
|
||||
@ -136,6 +154,9 @@ extern int FileCanWrite PARAMS((CONSFILE *, fd_set *, fd_set *));
|
||||
extern int FileBufEmpty PARAMS((CONSFILE *));
|
||||
extern int SetFlags PARAMS((int, int, int));
|
||||
extern char *StrDup PARAMS((char *));
|
||||
extern int ParseIACBuf PARAMS((CONSFILE *, void *, int *));
|
||||
extern void *MemMove PARAMS((void *, void *, size_t));
|
||||
extern char *StringChar PARAMS((STRING *, int, char));
|
||||
#if HAVE_OPENSSL
|
||||
extern SSL *FileGetSSL PARAMS((CONSFILE *));
|
||||
extern void FileSetSSL PARAMS((CONSFILE *, SSL *));
|
||||
|
2542
conserver/group.c
2542
conserver/group.c
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: group.h,v 5.41 2003/11/15 20:00:09 bryan Exp $
|
||||
* $Id: group.h,v 5.43 2003/12/20 06:11:53 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -36,11 +36,12 @@
|
||||
|
||||
/* timers used to have various things happen */
|
||||
#define T_STATE 0
|
||||
#define T_IDLE 1
|
||||
#define T_CIDLE 1
|
||||
#define T_MARK 2
|
||||
#define T_REINIT 3
|
||||
#define T_AUTOUP 4
|
||||
#define T_MAX 5 /* T_MAX *must* be last */
|
||||
#define T_ROLL 5
|
||||
#define T_MAX 6 /* T_MAX *must* be last */
|
||||
|
||||
/* return values used by CheckPass()
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: main.c,v 5.172 2003/11/20 13:56:39 bryan Exp $
|
||||
* $Id: main.c,v 5.178 2004/03/11 16:23:59 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -853,7 +853,7 @@ DumpDataStructures()
|
||||
|
||||
for (pGE = pGroups; pGE != (GRPENT *)0; pGE = pGE->pGEnext) {
|
||||
CONDDEBUG((1,
|
||||
"DumpDataStructures(): group: id=%u pid=%lu, port=%hu, imembers=%d",
|
||||
"DumpDataStructures(): group: id=%u port=%hu, pid=%lu, imembers=%d",
|
||||
pGE->id, pGE->port, (unsigned long)pGE->pid,
|
||||
pGE->imembers));
|
||||
|
||||
@ -864,8 +864,9 @@ DumpDataStructures()
|
||||
"DumpDataStructures(): server=%s, type=DEVICE",
|
||||
EMPTYSTR(pCE->server)));
|
||||
CONDDEBUG((1,
|
||||
"DumpDataStructures(): baud=%s, parity=%s",
|
||||
pCE->baud->acrate, pCE->parity->key));
|
||||
"DumpDataStructures(): baud=%s, parity=%s, device=%s",
|
||||
pCE->baud->acrate, pCE->parity->key,
|
||||
EMPTYSTR(pCE->device)));
|
||||
break;
|
||||
case EXEC:
|
||||
CONDDEBUG((1,
|
||||
@ -883,13 +884,13 @@ DumpDataStructures()
|
||||
"DumpDataStructures(): server=%s, type=HOST",
|
||||
EMPTYSTR(pCE->server)));
|
||||
CONDDEBUG((1,
|
||||
"DumpDataStructures(): host=%s, port=%hu, telnetState=%d",
|
||||
EMPTYSTR(pCE->host), pCE->port,
|
||||
pCE->telnetState));
|
||||
"DumpDataStructures(): host=%s, raw=%hu, netport=%hu, port=%hu, telnetState=%d",
|
||||
EMPTYSTR(pCE->host), pCE->raw, pCE->netport,
|
||||
pCE->port, pCE->telnetState));
|
||||
break;
|
||||
case UNKNOWN:
|
||||
case UNKNOWNTYPE:
|
||||
CONDDEBUG((1,
|
||||
"DumpDataStructures(): server=%s, type=UNKNOWN",
|
||||
"DumpDataStructures(): server=%s, type=UNKNOWNTYPE",
|
||||
EMPTYSTR(pCE->server)));
|
||||
break;
|
||||
}
|
||||
@ -1311,7 +1312,7 @@ main(argc, argv)
|
||||
optConf->redirect = FLAGFALSE;
|
||||
break;
|
||||
case 'S':
|
||||
fSyntaxOnly = 1;
|
||||
fSyntaxOnly++;
|
||||
break;
|
||||
case 'u':
|
||||
fAll = 1;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: master.c,v 5.123 2003/11/20 13:56:39 bryan Exp $
|
||||
* $Id: master.c,v 5.124 2003/12/25 19:22:00 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -433,7 +433,7 @@ DoNormalRead(pCLServing)
|
||||
{
|
||||
char *pcCmd;
|
||||
char *pcArgs;
|
||||
int nr, i;
|
||||
int nr, i, l;
|
||||
unsigned char acIn[BUFSIZ];
|
||||
|
||||
/* read connection */
|
||||
@ -442,208 +442,221 @@ DoNormalRead(pCLServing)
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < nr; ++i) {
|
||||
if ('\n' != acIn[i]) {
|
||||
BuildStringChar(acIn[i], pCLServing->accmd);
|
||||
while ((l = ParseIACBuf(pCLServing->fd, acIn, &nr)) >= 0) {
|
||||
if (l == 0) /* we ignore special OB_IAC stuff */
|
||||
continue;
|
||||
}
|
||||
if ((pCLServing->accmd->used > 1) &&
|
||||
('\r' ==
|
||||
pCLServing->accmd->string[pCLServing->accmd->used - 2])) {
|
||||
pCLServing->accmd->string[pCLServing->accmd->used - 2] =
|
||||
'\000';
|
||||
pCLServing->accmd->used--;
|
||||
}
|
||||
for (i = 0; i < l; ++i) {
|
||||
if ('\n' != acIn[i]) {
|
||||
BuildStringChar(acIn[i], pCLServing->accmd);
|
||||
continue;
|
||||
}
|
||||
if ((pCLServing->accmd->used > 1) &&
|
||||
('\r' ==
|
||||
pCLServing->accmd->string[pCLServing->accmd->used - 2])) {
|
||||
pCLServing->accmd->string[pCLServing->accmd->used - 2] =
|
||||
'\000';
|
||||
pCLServing->accmd->used--;
|
||||
}
|
||||
|
||||
/* process password here...before we corrupt accmd */
|
||||
if (pCLServing->iState == S_PASSWD) {
|
||||
if (CheckPasswd(pCLServing, pCLServing->accmd->string) !=
|
||||
AUTH_SUCCESS) {
|
||||
FileWrite(pCLServing->fd, FLAGFALSE,
|
||||
"invalid password\r\n", -1);
|
||||
/* process password here...before we corrupt accmd */
|
||||
if (pCLServing->iState == S_PASSWD) {
|
||||
if (CheckPasswd(pCLServing, pCLServing->accmd->string) !=
|
||||
AUTH_SUCCESS) {
|
||||
FileWrite(pCLServing->fd, FLAGFALSE,
|
||||
"invalid password\r\n", -1);
|
||||
BuildString((char *)0, pCLServing->accmd);
|
||||
DropMasterClient(pCLServing, FLAGFALSE);
|
||||
return;
|
||||
}
|
||||
Verbose("<master> login %s", pCLServing->acid->string);
|
||||
FileWrite(pCLServing->fd, FLAGFALSE, "ok\r\n", 4);
|
||||
pCLServing->iState = S_NORMAL;
|
||||
BuildString((char *)0, pCLServing->accmd);
|
||||
DropMasterClient(pCLServing, FLAGFALSE);
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
Verbose("<master> login %s", pCLServing->acid->string);
|
||||
FileWrite(pCLServing->fd, FLAGFALSE, "ok\r\n", 4);
|
||||
pCLServing->iState = S_NORMAL;
|
||||
BuildString((char *)0, pCLServing->accmd);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((char *)0 != (pcArgs = strchr(pCLServing->accmd->string, ':'))) {
|
||||
*pcArgs++ = '\000';
|
||||
} else if ((char *)0 !=
|
||||
(pcArgs = strchr(pCLServing->accmd->string, ' '))) {
|
||||
*pcArgs++ = '\000';
|
||||
}
|
||||
if (pcArgs != (char *)0)
|
||||
pcArgs = PruneSpace(pcArgs);
|
||||
pcCmd = PruneSpace(pCLServing->accmd->string);
|
||||
if (strcmp(pcCmd, "help") == 0) {
|
||||
static char *apcHelp1[] = {
|
||||
"exit disconnect\r\n",
|
||||
"help this help message\r\n",
|
||||
"login log in\r\n",
|
||||
#if HAVE_OPENSSL
|
||||
"ssl start ssl session\r\n",
|
||||
#endif
|
||||
(char *)0
|
||||
};
|
||||
static char *apcHelp2[] = {
|
||||
"call provide port for given console\r\n",
|
||||
"exit disconnect\r\n",
|
||||
"groups provide ports for group leaders\r\n",
|
||||
"help this help message\r\n",
|
||||
"master provide a list of master servers\r\n",
|
||||
"pid provide pid of master process\r\n",
|
||||
"quit* terminate conserver (SIGTERM)\r\n",
|
||||
"restart* restart conserver (SIGHUP)\r\n",
|
||||
"version provide version info for server\r\n",
|
||||
"* = requires admin privileges\r\n",
|
||||
(char *)0
|
||||
};
|
||||
char **ppc;
|
||||
for (ppc =
|
||||
(pCLServing->iState == S_IDENT ? apcHelp1 : apcHelp2);
|
||||
(char *)0 != *ppc; ++ppc) {
|
||||
FileWrite(pCLServing->fd, FLAGTRUE, *ppc, -1);
|
||||
if ((char *)0 !=
|
||||
(pcArgs = strchr(pCLServing->accmd->string, ':'))) {
|
||||
*pcArgs++ = '\000';
|
||||
} else if ((char *)0 !=
|
||||
(pcArgs = strchr(pCLServing->accmd->string, ' '))) {
|
||||
*pcArgs++ = '\000';
|
||||
}
|
||||
FileWrite(pCLServing->fd, FLAGFALSE, (char *)0, 0);
|
||||
} else if (strcmp(pcCmd, "exit") == 0) {
|
||||
FileWrite(pCLServing->fd, FLAGFALSE, "goodbye\r\n", -1);
|
||||
DropMasterClient(pCLServing, FLAGFALSE);
|
||||
return;
|
||||
if (pcArgs != (char *)0)
|
||||
pcArgs = PruneSpace(pcArgs);
|
||||
pcCmd = PruneSpace(pCLServing->accmd->string);
|
||||
if (strcmp(pcCmd, "help") == 0) {
|
||||
static char *apcHelp1[] = {
|
||||
"exit disconnect\r\n",
|
||||
"help this help message\r\n",
|
||||
"login log in\r\n",
|
||||
#if HAVE_OPENSSL
|
||||
} else if (pCLServing->iState == S_IDENT &&
|
||||
strcmp(pcCmd, "ssl") == 0) {
|
||||
FileWrite(pCLServing->fd, FLAGFALSE, "ok\r\n", -1);
|
||||
if (!AttemptSSL(pCLServing)) {
|
||||
"ssl start ssl session\r\n",
|
||||
#endif
|
||||
(char *)0
|
||||
};
|
||||
static char *apcHelp2[] = {
|
||||
"call provide port for given console\r\n",
|
||||
"exit disconnect\r\n",
|
||||
"groups provide ports for group leaders\r\n",
|
||||
"help this help message\r\n",
|
||||
"master provide a list of master servers\r\n",
|
||||
"pid provide pid of master process\r\n",
|
||||
"quit* terminate conserver (SIGTERM)\r\n",
|
||||
"restart* restart conserver (SIGHUP)\r\n",
|
||||
"version provide version info for server\r\n",
|
||||
"* = requires admin privileges\r\n",
|
||||
(char *)0
|
||||
};
|
||||
char **ppc;
|
||||
for (ppc =
|
||||
(pCLServing->iState == S_IDENT ? apcHelp1 : apcHelp2);
|
||||
(char *)0 != *ppc; ++ppc) {
|
||||
FileWrite(pCLServing->fd, FLAGTRUE, *ppc, -1);
|
||||
}
|
||||
FileWrite(pCLServing->fd, FLAGFALSE, (char *)0, 0);
|
||||
} else if (strcmp(pcCmd, "exit") == 0) {
|
||||
FileWrite(pCLServing->fd, FLAGFALSE, "goodbye\r\n", -1);
|
||||
DropMasterClient(pCLServing, FLAGFALSE);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
} else if (pCLServing->iState == S_IDENT &&
|
||||
strcmp(pcCmd, "login") == 0) {
|
||||
#if HAVE_OPENSSL
|
||||
if (config->sslrequired == FLAGTRUE &&
|
||||
FileGetType(pCLServing->fd) != SSLSocket) {
|
||||
FileWrite(pCLServing->fd, FLAGFALSE,
|
||||
"encryption required\r\n", -1);
|
||||
} else {
|
||||
} else if (pCLServing->iState == S_IDENT &&
|
||||
strcmp(pcCmd, "ssl") == 0) {
|
||||
FileWrite(pCLServing->fd, FLAGFALSE, "ok\r\n", -1);
|
||||
if (!AttemptSSL(pCLServing)) {
|
||||
DropMasterClient(pCLServing, FLAGFALSE);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (pcArgs == (char *)0) {
|
||||
} else if (pCLServing->iState == S_IDENT &&
|
||||
strcmp(pcCmd, "login") == 0) {
|
||||
#if HAVE_OPENSSL
|
||||
if (config->sslrequired == FLAGTRUE &&
|
||||
FileGetType(pCLServing->fd) != SSLSocket) {
|
||||
FileWrite(pCLServing->fd, FLAGFALSE,
|
||||
"login requires argument\r\n", -1);
|
||||
"encryption required\r\n", -1);
|
||||
} else {
|
||||
BuildString((char *)0, pCLServing->username);
|
||||
BuildString((char *)0, pCLServing->acid);
|
||||
BuildString(pcArgs, pCLServing->username);
|
||||
BuildString(pcArgs, pCLServing->acid);
|
||||
BuildStringChar('@', pCLServing->acid);
|
||||
BuildString(pCLServing->peername->string,
|
||||
pCLServing->acid);
|
||||
if (pCLServing->caccess == 't' ||
|
||||
CheckPasswd(pCLServing, "") == AUTH_SUCCESS) {
|
||||
pCLServing->iState = S_NORMAL;
|
||||
Verbose("<master> login %s",
|
||||
pCLServing->acid->string);
|
||||
FileWrite(pCLServing->fd, FLAGFALSE, "ok\r\n", 4);
|
||||
} else {
|
||||
FilePrint(pCLServing->fd, FLAGFALSE,
|
||||
"passwd? %s\r\n", myHostname);
|
||||
pCLServing->iState = S_PASSWD;
|
||||
}
|
||||
}
|
||||
#if HAVE_OPENSSL
|
||||
}
|
||||
#endif
|
||||
} else if (pCLServing->iState == S_NORMAL &&
|
||||
strcmp(pcCmd, "master") == 0) {
|
||||
int iSep = 1;
|
||||
|
||||
if ((GRPENT *)0 != pGroups) {
|
||||
struct sockaddr_in lcl;
|
||||
socklen_t so = sizeof(lcl);
|
||||
if (-1 ==
|
||||
getsockname(FileFDNum(pCLServing->fd),
|
||||
(struct sockaddr *)&lcl, &so)) {
|
||||
FileWrite(pCLServing->fd, FLAGFALSE,
|
||||
"getsockname failed, try again later\r\n",
|
||||
-1);
|
||||
Error("Master(): getsockname(%u): %s",
|
||||
FileFDNum(pCLServing->fd), strerror(errno));
|
||||
Bye(EX_OSERR);
|
||||
if (pcArgs == (char *)0) {
|
||||
FileWrite(pCLServing->fd, FLAGFALSE,
|
||||
"login requires argument\r\n", -1);
|
||||
} else {
|
||||
BuildString((char *)0, pCLServing->username);
|
||||
BuildString((char *)0, pCLServing->acid);
|
||||
BuildString(pcArgs, pCLServing->username);
|
||||
BuildString(pcArgs, pCLServing->acid);
|
||||
BuildStringChar('@', pCLServing->acid);
|
||||
BuildString(pCLServing->peername->string,
|
||||
pCLServing->acid);
|
||||
if (pCLServing->caccess == 't' ||
|
||||
CheckPasswd(pCLServing, "") == AUTH_SUCCESS) {
|
||||
pCLServing->iState = S_NORMAL;
|
||||
Verbose("<master> login %s",
|
||||
pCLServing->acid->string);
|
||||
FileWrite(pCLServing->fd, FLAGFALSE, "ok\r\n",
|
||||
4);
|
||||
} else {
|
||||
FilePrint(pCLServing->fd, FLAGFALSE,
|
||||
"passwd? %s\r\n", myHostname);
|
||||
pCLServing->iState = S_PASSWD;
|
||||
}
|
||||
}
|
||||
#if HAVE_OPENSSL
|
||||
}
|
||||
FilePrint(pCLServing->fd, FLAGTRUE, "@%s",
|
||||
inet_ntoa(lcl.sin_addr));
|
||||
iSep = 0;
|
||||
}
|
||||
if (config->redirect == FLAGTRUE) {
|
||||
REMOTE *pRC;
|
||||
for (pRC = pRCUniq; (REMOTE *)0 != pRC; pRC = pRC->pRCuniq) {
|
||||
FilePrint(pCLServing->fd, FLAGTRUE, ":@%s" + iSep,
|
||||
pRC->rhost);
|
||||
#endif
|
||||
} else if (pCLServing->iState == S_NORMAL &&
|
||||
strcmp(pcCmd, "master") == 0) {
|
||||
int iSep = 1;
|
||||
|
||||
if ((GRPENT *)0 != pGroups) {
|
||||
struct sockaddr_in lcl;
|
||||
socklen_t so = sizeof(lcl);
|
||||
if (-1 ==
|
||||
getsockname(FileFDNum(pCLServing->fd),
|
||||
(struct sockaddr *)&lcl, &so)) {
|
||||
FileWrite(pCLServing->fd, FLAGFALSE,
|
||||
"getsockname failed, try again later\r\n",
|
||||
-1);
|
||||
Error("Master(): getsockname(%u): %s",
|
||||
FileFDNum(pCLServing->fd), strerror(errno));
|
||||
Bye(EX_OSERR);
|
||||
}
|
||||
FilePrint(pCLServing->fd, FLAGTRUE, "@%s",
|
||||
inet_ntoa(lcl.sin_addr));
|
||||
iSep = 0;
|
||||
}
|
||||
}
|
||||
FileWrite(pCLServing->fd, FLAGFALSE, "\r\n", -1);
|
||||
} else if (pCLServing->iState == S_NORMAL &&
|
||||
strcmp(pcCmd, "pid") == 0) {
|
||||
FilePrint(pCLServing->fd, FLAGFALSE, "%lu\r\n",
|
||||
(unsigned long)thepid);
|
||||
} else if (pCLServing->iState == S_NORMAL &&
|
||||
strcmp(pcCmd, "version") == 0) {
|
||||
FilePrint(pCLServing->fd, FLAGFALSE, "version `%s'\r\n",
|
||||
THIS_VERSION);
|
||||
} else if (pCLServing->iState == S_NORMAL &&
|
||||
strcmp(pcCmd, "quit") == 0) {
|
||||
if (ConsentUserOk(pADList, pCLServing->username->string) == 1) {
|
||||
Verbose("quit command by %s", pCLServing->acid->string);
|
||||
FileWrite(pCLServing->fd, FLAGFALSE,
|
||||
"ok -- terminated\r\n", -1);
|
||||
DropMasterClient(pCLServing, FLAGFALSE);
|
||||
kill(thepid, SIGTERM);
|
||||
return;
|
||||
} else
|
||||
FileWrite(pCLServing->fd, FLAGFALSE,
|
||||
"unauthorized command\r\n", -1);
|
||||
} else if (pCLServing->iState == S_NORMAL &&
|
||||
strcmp(pcCmd, "restart") == 0) {
|
||||
if (ConsentUserOk(pADList, pCLServing->username->string) == 1) {
|
||||
FileWrite(pCLServing->fd, FLAGFALSE,
|
||||
"ok -- restarting\r\n", -1);
|
||||
Verbose("restart command by %s", pCLServing->acid->string);
|
||||
kill(thepid, SIGHUP);
|
||||
} else
|
||||
FileWrite(pCLServing->fd, FLAGFALSE,
|
||||
"unauthorized command\r\n", -1);
|
||||
} else if (pCLServing->iState == S_NORMAL &&
|
||||
strcmp(pcCmd, "groups") == 0) {
|
||||
int iSep = 1;
|
||||
GRPENT *pGE;
|
||||
if (config->redirect == FLAGTRUE) {
|
||||
REMOTE *pRC;
|
||||
for (pRC = pRCUniq; (REMOTE *)0 != pRC;
|
||||
pRC = pRC->pRCuniq) {
|
||||
FilePrint(pCLServing->fd, FLAGTRUE, ":@%s" + iSep,
|
||||
pRC->rhost);
|
||||
iSep = 0;
|
||||
}
|
||||
}
|
||||
FileWrite(pCLServing->fd, FLAGFALSE, "\r\n", -1);
|
||||
} else if (pCLServing->iState == S_NORMAL &&
|
||||
strcmp(pcCmd, "pid") == 0) {
|
||||
FilePrint(pCLServing->fd, FLAGFALSE, "%lu\r\n",
|
||||
(unsigned long)thepid);
|
||||
} else if (pCLServing->iState == S_NORMAL &&
|
||||
strcmp(pcCmd, "version") == 0) {
|
||||
FilePrint(pCLServing->fd, FLAGFALSE, "version `%s'\r\n",
|
||||
THIS_VERSION);
|
||||
} else if (pCLServing->iState == S_NORMAL &&
|
||||
strcmp(pcCmd, "quit") == 0) {
|
||||
if (ConsentUserOk(pADList, pCLServing->username->string) ==
|
||||
1) {
|
||||
Verbose("quit command by %s",
|
||||
pCLServing->acid->string);
|
||||
FileWrite(pCLServing->fd, FLAGFALSE,
|
||||
"ok -- terminated\r\n", -1);
|
||||
DropMasterClient(pCLServing, FLAGFALSE);
|
||||
kill(thepid, SIGTERM);
|
||||
return;
|
||||
} else
|
||||
FileWrite(pCLServing->fd, FLAGFALSE,
|
||||
"unauthorized command\r\n", -1);
|
||||
} else if (pCLServing->iState == S_NORMAL &&
|
||||
strcmp(pcCmd, "restart") == 0) {
|
||||
if (ConsentUserOk(pADList, pCLServing->username->string) ==
|
||||
1) {
|
||||
FileWrite(pCLServing->fd, FLAGFALSE,
|
||||
"ok -- restarting\r\n", -1);
|
||||
Verbose("restart command by %s",
|
||||
pCLServing->acid->string);
|
||||
kill(thepid, SIGHUP);
|
||||
} else
|
||||
FileWrite(pCLServing->fd, FLAGFALSE,
|
||||
"unauthorized command\r\n", -1);
|
||||
} else if (pCLServing->iState == S_NORMAL &&
|
||||
strcmp(pcCmd, "groups") == 0) {
|
||||
int iSep = 1;
|
||||
GRPENT *pGE;
|
||||
|
||||
for (pGE = pGroups; pGE != (GRPENT *)0; pGE = pGE->pGEnext) {
|
||||
if (0 == pGE->imembers)
|
||||
continue;
|
||||
FilePrint(pCLServing->fd, FLAGTRUE, ":%hu" + iSep,
|
||||
pGE->port);
|
||||
iSep = 0;
|
||||
for (pGE = pGroups; pGE != (GRPENT *)0; pGE = pGE->pGEnext) {
|
||||
if (0 == pGE->imembers)
|
||||
continue;
|
||||
FilePrint(pCLServing->fd, FLAGTRUE, ":%hu" + iSep,
|
||||
pGE->port);
|
||||
iSep = 0;
|
||||
}
|
||||
FileWrite(pCLServing->fd, FLAGFALSE, "\r\n", 2);
|
||||
} else if (pCLServing->iState == S_NORMAL &&
|
||||
strcmp(pcCmd, "call") == 0) {
|
||||
if (pcArgs == (char *)0)
|
||||
FileWrite(pCLServing->fd, FLAGFALSE,
|
||||
"call requires argument\r\n", -1);
|
||||
else
|
||||
CommandCall(pCLServing, pcArgs);
|
||||
} else {
|
||||
FileWrite(pCLServing->fd, FLAGFALSE, "unknown command\r\n",
|
||||
-1);
|
||||
}
|
||||
FileWrite(pCLServing->fd, FLAGFALSE, "\r\n", 2);
|
||||
} else if (pCLServing->iState == S_NORMAL &&
|
||||
strcmp(pcCmd, "call") == 0) {
|
||||
if (pcArgs == (char *)0)
|
||||
FileWrite(pCLServing->fd, FLAGFALSE,
|
||||
"call requires argument\r\n", -1);
|
||||
else
|
||||
CommandCall(pCLServing, pcArgs);
|
||||
} else {
|
||||
FileWrite(pCLServing->fd, FLAGFALSE, "unknown command\r\n",
|
||||
-1);
|
||||
BuildString((char *)0, pCLServing->accmd);
|
||||
}
|
||||
BuildString((char *)0, pCLServing->accmd);
|
||||
nr -= l;
|
||||
MemMove(acIn, acIn + l, nr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -872,9 +885,10 @@ Master()
|
||||
}
|
||||
|
||||
/* set to non-blocking and wrap in a File object */
|
||||
if (SetFlags(cfd, O_NONBLOCK, 0))
|
||||
if (SetFlags(cfd, O_NONBLOCK, 0)) {
|
||||
pCLmfree->fd = FileOpenFD(cfd, simpleSocket);
|
||||
else
|
||||
FileSetQuoteIAC(pCLmfree->fd, FLAGTRUE);
|
||||
} else
|
||||
pCLmfree->fd = (CONSFILE *)0;
|
||||
|
||||
if ((CONSFILE *)0 == pCLmfree->fd) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: readcfg.c,v 5.158 2003/11/20 13:56:39 bryan Exp $
|
||||
* $Id: readcfg.c,v 5.168 2004/03/11 16:23:59 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -605,6 +605,8 @@ DestroyParserDefaultOrConsole(c, ph, pt)
|
||||
free(c->devicesubst);
|
||||
if (c->execsubst != (char *)0)
|
||||
free(c->execsubst);
|
||||
if (c->initsubst != (char *)0)
|
||||
free(c->initsubst);
|
||||
if (c->logfile != (char *)0)
|
||||
free(c->logfile);
|
||||
if (c->initcmd != (char *)0)
|
||||
@ -653,7 +655,7 @@ ApplyDefault(d, c)
|
||||
CONSENT *c;
|
||||
#endif
|
||||
{
|
||||
if (d->type != UNKNOWN)
|
||||
if (d->type != UNKNOWNTYPE)
|
||||
c->type = d->type;
|
||||
if (d->breakNum != 0)
|
||||
c->breakNum = d->breakNum;
|
||||
@ -663,8 +665,12 @@ ApplyDefault(d, c)
|
||||
c->parity = d->parity;
|
||||
if (d->idletimeout != 0)
|
||||
c->idletimeout = d->idletimeout;
|
||||
if (d->logfilemax != 0)
|
||||
c->logfilemax = d->logfilemax;
|
||||
if (d->port != 0)
|
||||
c->port = d->port;
|
||||
if (d->netport != 0)
|
||||
c->netport = d->netport;
|
||||
if (d->portinc != 0)
|
||||
c->portinc = d->portinc;
|
||||
if (d->portbase != 0)
|
||||
@ -737,6 +743,12 @@ ApplyDefault(d, c)
|
||||
if ((c->execsubst = StrDup(d->execsubst)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
if (d->initsubst != (char *)0) {
|
||||
if (c->initsubst != (char *)0)
|
||||
free(c->initsubst);
|
||||
if ((c->initsubst = StrDup(d->initsubst)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
if (d->logfile != (char *)0) {
|
||||
if (c->logfile != (char *)0)
|
||||
free(c->logfile);
|
||||
@ -951,98 +963,235 @@ ProcessDevice(c, id)
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ProcessDevicesubst(CONSENT *c, char *id)
|
||||
ProcessSubst(CONSENT *pCE, char **repl, char **str, char *name, char *id)
|
||||
#else
|
||||
ProcessDevicesubst(c, id)
|
||||
CONSENT *c;
|
||||
ProcessSubst(pCE, repl, str, name, id)
|
||||
CONSENT *pCE;
|
||||
char **repl;
|
||||
char **str;
|
||||
char *name;
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
/*
|
||||
* (CONSENT *pCE) and (char **repl) are used when a replacement is to
|
||||
* actually happen...repl is the string to munch, pCE holds the data.
|
||||
*
|
||||
* (char **str) is used to store a copy of (char *id), if it passes
|
||||
* the format check.
|
||||
*
|
||||
* the idea is that this is first called when the config file is read,
|
||||
* putting the result in (char **str). then we call it again, near
|
||||
* the end, permuting (char **repl) with values from (CONSENT *pCE) with
|
||||
* the saved string now coming in as (char *id). got it?
|
||||
*
|
||||
* you could pass all arguments in...then both types of actions occur.
|
||||
*/
|
||||
char *p;
|
||||
char *repfmt[255];
|
||||
unsigned short repnum;
|
||||
int i;
|
||||
|
||||
if (c->devicesubst != (char *)0) {
|
||||
free(c->devicesubst);
|
||||
c->devicesubst = (char *)0;
|
||||
enum repstate {
|
||||
REP_BEGIN,
|
||||
REP_LTR,
|
||||
REP_EQ,
|
||||
REP_INT,
|
||||
REP_END
|
||||
} state;
|
||||
|
||||
if (str != (char **)0) {
|
||||
if (*str != (char *)0) {
|
||||
free(*str);
|
||||
*str = (char *)0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((id == (char *)0) || (*id == '\000'))
|
||||
return;
|
||||
|
||||
if (strlen(id) < 3) {
|
||||
if (isMaster)
|
||||
Error("incomplete `devicesubst' option [%s:%d]", file, line);
|
||||
return;
|
||||
repnum = 0;
|
||||
state = REP_BEGIN;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
repfmt[i] = (char *)0;
|
||||
|
||||
for (p = id; *p != '\000'; p++) {
|
||||
switch (state) {
|
||||
case REP_BEGIN:
|
||||
/* must be printable */
|
||||
if (*p == ',' || !isgraph((int)(*p)))
|
||||
goto subst_err;
|
||||
|
||||
/* make sure we haven't seen this replacement char yet */
|
||||
repnum = (unsigned short)(*p);
|
||||
if (repfmt[repnum] != (char *)0) {
|
||||
if (isMaster)
|
||||
Error
|
||||
("substitution characters of `%s' option are the same [%s:%d]",
|
||||
name, file, line);
|
||||
return;
|
||||
}
|
||||
state = REP_LTR;
|
||||
break;
|
||||
case REP_LTR:
|
||||
if (*p != '=')
|
||||
goto subst_err;
|
||||
state = REP_EQ;
|
||||
break;
|
||||
case REP_EQ:
|
||||
repfmt[repnum] = p;
|
||||
if (*p == 'h' || *p == 'c' || *p == 'p' || *p == 'P')
|
||||
state = REP_INT;
|
||||
else
|
||||
goto subst_err;
|
||||
break;
|
||||
case REP_INT:
|
||||
if (*p == 'd' || *p == 'x' || *p == 'X') {
|
||||
if (*(repfmt[repnum]) != 'p' &&
|
||||
*(repfmt[repnum]) != 'P')
|
||||
goto subst_err;
|
||||
state = REP_END;
|
||||
} else if (*p == 's') {
|
||||
if (*(repfmt[repnum]) != 'h' &&
|
||||
*(repfmt[repnum]) != 'c')
|
||||
goto subst_err;
|
||||
state = REP_END;
|
||||
} else if (!isdigit((int)(*p)))
|
||||
goto subst_err;
|
||||
break;
|
||||
case REP_END:
|
||||
if (*p != ',')
|
||||
goto subst_err;
|
||||
state = REP_BEGIN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (id[0] == id[1]) {
|
||||
if (state != REP_END) {
|
||||
subst_err:
|
||||
if (isMaster)
|
||||
Error
|
||||
("first two characters of `devicesubst' option are the same [%s:%d]",
|
||||
file, line);
|
||||
("invalid `%s' specification `%s' (char #%d: `%c') [%s:%d]",
|
||||
name, id, (p - id) + 1, *p, file, line);
|
||||
return;
|
||||
}
|
||||
|
||||
for (p = id + 2; *p != '\000'; p++)
|
||||
if (!isdigit((int)(*p)))
|
||||
break;
|
||||
/* if it wasn't a number followed by a d/x/X */
|
||||
if (!((*p == 'd' || *p == 'x' || *p == 'X') && *(p + 1) == '\000')) {
|
||||
if (isMaster)
|
||||
Error("invalid `execsubst' specification `%s' [%s:%d]", id,
|
||||
file, line);
|
||||
return;
|
||||
if (str != (char **)0) {
|
||||
if ((*str = StrDup(id)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
|
||||
if ((c->devicesubst = StrDup(id)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
if (pCE != (CONSENT *)0 && repl != (char **)0) {
|
||||
static STRING *result = (STRING *)0;
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ProcessExecsubst(CONSENT *c, char *id)
|
||||
#else
|
||||
ProcessExecsubst(c, id)
|
||||
CONSENT *c;
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
char *p;
|
||||
if (result == (STRING *)0)
|
||||
result = AllocString();
|
||||
BuildString((char *)0, result);
|
||||
|
||||
if (c->execsubst != (char *)0) {
|
||||
free(c->execsubst);
|
||||
c->execsubst = (char *)0;
|
||||
for (p = *repl; *p != '\000'; p++) {
|
||||
if (repfmt[(unsigned short)(*p)] != (char *)0) {
|
||||
char *r = repfmt[(unsigned short)(*p)];
|
||||
int plen = 0;
|
||||
char *c = (char *)0;
|
||||
int o = 0;
|
||||
|
||||
if (*r == 'h' || *r == 'c') {
|
||||
/* check the pattern for a length */
|
||||
if (isdigit((int)(*(r + 1))))
|
||||
plen = atoi(r + 1);
|
||||
|
||||
if (*r == 'h')
|
||||
c = pCE->host;
|
||||
else if (*r == 'c')
|
||||
c = pCE->server;
|
||||
plen -= strlen(c);
|
||||
|
||||
/* pad it out, if necessary */
|
||||
for (i = 0; i < plen; i++)
|
||||
BuildStringChar(' ', result);
|
||||
|
||||
/* throw in the string */
|
||||
BuildString(c, result);
|
||||
} else {
|
||||
unsigned short port = 0;
|
||||
unsigned short base = 0;
|
||||
int padzero = 0;
|
||||
static STRING *num = (STRING *)0;
|
||||
|
||||
if (num == (STRING *)0)
|
||||
num = AllocString();
|
||||
BuildString((char *)0, num);
|
||||
|
||||
if (*r == 'p')
|
||||
port = pCE->port;
|
||||
if (*r == 'P')
|
||||
port = pCE->netport;
|
||||
|
||||
/* check the pattern for a length and padding */
|
||||
for (c = r + 1; *c != '\000'; c++)
|
||||
if (!isdigit((int)(*c)))
|
||||
break;
|
||||
if (c != r + 1) {
|
||||
plen = atoi(r + 1);
|
||||
padzero = (r[1] == '0');
|
||||
}
|
||||
|
||||
/* check for base */
|
||||
switch (*c) {
|
||||
case 'd':
|
||||
base = 10;
|
||||
break;
|
||||
case 'x':
|
||||
case 'X':
|
||||
base = 16;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
while (port >= base) {
|
||||
if (port % base >= 10)
|
||||
BuildStringChar((port % base) - 10 +
|
||||
(*c == 'x' ? 'a' : 'A'), num);
|
||||
else
|
||||
BuildStringChar((port % base) + '0', num);
|
||||
port /= base;
|
||||
}
|
||||
if (port >= 10)
|
||||
BuildStringChar(port - 10 +
|
||||
(*c == 'x' ? 'a' : 'A'), num);
|
||||
else
|
||||
BuildStringChar(port + '0', num);
|
||||
|
||||
/* if we're supposed to be a certain length, pad it */
|
||||
while (num->used - 1 < plen) {
|
||||
if (padzero == 0)
|
||||
BuildStringChar(' ', num);
|
||||
else
|
||||
BuildStringChar('0', num);
|
||||
}
|
||||
|
||||
/* reverse the text to put it in forward order */
|
||||
o = num->used - 1;
|
||||
for (i = 0; i < o / 2; i++) {
|
||||
char temp;
|
||||
|
||||
temp = num->string[i];
|
||||
num->string[i]
|
||||
= num->string[o - i - 1];
|
||||
num->string[o - i - 1] = temp;
|
||||
}
|
||||
BuildStringN(num->string, o, result);
|
||||
}
|
||||
} else
|
||||
BuildStringChar(*p, result);
|
||||
}
|
||||
free(*repl);
|
||||
if ((*repl = StrDup(result->string)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
|
||||
if ((id == (char *)0) || (*id == '\000'))
|
||||
return;
|
||||
|
||||
if (strlen(id) < 3) {
|
||||
if (isMaster)
|
||||
Error("incomplete `execsubst' option [%s:%d]", file, line);
|
||||
return;
|
||||
}
|
||||
|
||||
if (id[0] == id[1]) {
|
||||
if (isMaster)
|
||||
Error
|
||||
("first two characters of `execsubst' option are the same [%s:%d]",
|
||||
file, line);
|
||||
return;
|
||||
}
|
||||
|
||||
for (p = id + 2; *p != '\000'; p++)
|
||||
if (!isdigit((int)(*p)))
|
||||
break;
|
||||
/* if it wasn't a number followed by a d/x/X */
|
||||
if (!((*p == 'd' || *p == 'x' || *p == 'X') && *(p + 1) == '\000')) {
|
||||
if (isMaster)
|
||||
Error("invalid `execsubst' specification `%s' [%s:%d]", id,
|
||||
file, line);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((c->execsubst = StrDup(id)) == (char *)0)
|
||||
OutOfMem();
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1066,7 +1215,8 @@ DefaultItemDevicesubst(id)
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "DefaultItemDevicesubst(%s) [%s:%d]", id, file, line));
|
||||
ProcessDevicesubst(parserDefaultTemp, id);
|
||||
ProcessSubst((CONSENT *)0, (char **)0,
|
||||
&(parserDefaultTemp->devicesubst), "devicesubst", id);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1078,7 +1228,21 @@ DefaultItemExecsubst(id)
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "DefaultItemExecsubst(%s) [%s:%d]", id, file, line));
|
||||
ProcessExecsubst(parserDefaultTemp, id);
|
||||
ProcessSubst((CONSENT *)0, (char **)0, &(parserDefaultTemp->execsubst),
|
||||
"execsubst", id);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
DefaultItemInitsubst(char *id)
|
||||
#else
|
||||
DefaultItemInitsubst(id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "DefaultItemInitsubst(%s) [%s:%d]", id, file, line));
|
||||
ProcessSubst((CONSENT *)0, (char **)0, &(parserDefaultTemp->initsubst),
|
||||
"initsubst", id);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1299,6 +1463,66 @@ DefaultItemLogfile(id)
|
||||
ProcessLogfile(parserDefaultTemp, id);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ProcessLogfilemax(CONSENT *c, char *id)
|
||||
#else
|
||||
ProcessLogfilemax(c, id)
|
||||
CONSENT *c;
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
char *p;
|
||||
off_t v = 0;
|
||||
|
||||
c->logfilemax = 0;
|
||||
|
||||
if (id == (char *)0 || id[0] == '\000')
|
||||
return;
|
||||
|
||||
for (p = id; *p != '\000'; p++) {
|
||||
if (!isdigit((int)(*p)))
|
||||
break;
|
||||
v = v * 10 + (*p - '0');
|
||||
}
|
||||
|
||||
/* if it wasn't just numbers */
|
||||
if (*p != '\000') {
|
||||
if ((*p == 'k' || *p == 'K') && *(p + 1) == '\000') {
|
||||
v *= 1024;
|
||||
} else if ((*p == 'm' || *p == 'M') && *(p + 1) == '\000') {
|
||||
v *= 1024 * 1024;
|
||||
} else {
|
||||
if (isMaster)
|
||||
Error("invalid `logfilemax' specification `%s' [%s:%d]",
|
||||
id, file, line);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (v < 2048) {
|
||||
if (isMaster)
|
||||
Error
|
||||
("invalid `logfilemax' specification `%s' (must be >= 2K) [%s:%d]",
|
||||
id, file, line);
|
||||
return;
|
||||
}
|
||||
|
||||
c->logfilemax = v;
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
DefaultItemLogfilemax(char *id)
|
||||
#else
|
||||
DefaultItemLogfilemax(id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "DefaultItemLogfilemax(%s) [%s:%d]", id, file, line));
|
||||
ProcessLogfilemax(parserDefaultTemp, id);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
DefaultItemInitcmd(char *id)
|
||||
@ -1498,9 +1722,7 @@ ProcessPort(c, id)
|
||||
|
||||
/* if it was a number */
|
||||
if (*p == '\000') {
|
||||
if (((c->port = (unsigned short)atoi(id)) == 0) && isMaster)
|
||||
Error("invalid port number `%s' [%s:%d]", id, file, line);
|
||||
return;
|
||||
c->port = (unsigned short)atoi(id) + 1;
|
||||
} else {
|
||||
/* non-numeric */
|
||||
struct servent *se;
|
||||
@ -1511,9 +1733,7 @@ ProcessPort(c, id)
|
||||
id, file, line);
|
||||
return;
|
||||
} else {
|
||||
if (((c->port = ntohs((unsigned short)se->s_port)) == 0) &&
|
||||
isMaster)
|
||||
Error("invalid port number `%s' [%s:%d]", id, file, line);
|
||||
c->port = ntohs((unsigned short)se->s_port) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1560,16 +1780,24 @@ ProcessPortbase(c, id)
|
||||
c->portbase = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* if we have -1, allow it (we allow >= -1 now) */
|
||||
if (id[0] == '-' && id[1] == '1' && id[2] == '\000') {
|
||||
c->portbase = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
for (p = id; *p != '\000'; p++)
|
||||
if (!isdigit((int)(*p)))
|
||||
break;
|
||||
|
||||
/* if it wasn't a number */
|
||||
if (*p != '\000') {
|
||||
if (isMaster)
|
||||
Error("invalid portbase number `%s' [%s:%d]", id, file, line);
|
||||
return;
|
||||
}
|
||||
c->portbase = (unsigned short)atoi(id) + 1;
|
||||
c->portbase = (unsigned short)atoi(id) + 2;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1608,6 +1836,41 @@ DefaultItemPortinc(id)
|
||||
ProcessPortinc(parserDefaultTemp, id);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ProcessProtocol(CONSENT *c, char *id)
|
||||
#else
|
||||
ProcessProtocol(c, id)
|
||||
CONSENT *c;
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
c->raw = 0;
|
||||
if ((id == (char *)0) || (*id == '\000'))
|
||||
return;
|
||||
|
||||
if (strcmp(id, "telnet") == 0)
|
||||
return;
|
||||
if (strcmp(id, "raw") == 0) {
|
||||
c->raw = 1;
|
||||
return;
|
||||
}
|
||||
if (isMaster)
|
||||
Error("invalid protocol name `%s' [%s:%d]", id, file, line);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
DefaultItemProtocol(char *id)
|
||||
#else
|
||||
DefaultItemProtocol(id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "DefaultItemProtocol(%s) [%s:%d]", id, file, line));
|
||||
ProcessProtocol(parserDefaultTemp, id);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ProcessIdletimeout(CONSENT *c, char *id)
|
||||
@ -1877,7 +2140,7 @@ ProcessType(c, id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
CONSTYPE t = UNKNOWN;
|
||||
CONSTYPE t = UNKNOWNTYPE;
|
||||
if ((id == (char *)0) || (*id == '\000')) {
|
||||
c->type = t;
|
||||
return;
|
||||
@ -1888,7 +2151,7 @@ ProcessType(c, id)
|
||||
t = EXEC;
|
||||
else if (strcasecmp("host", id) == 0)
|
||||
t = HOST;
|
||||
if (t == UNKNOWN) {
|
||||
if (t == UNKNOWNTYPE) {
|
||||
if (isMaster)
|
||||
Error("invalid console type `%s' [%s:%d]", id, file, line);
|
||||
} else
|
||||
@ -2043,13 +2306,33 @@ ConsoleEnd()
|
||||
invalid = 1;
|
||||
}
|
||||
break;
|
||||
case UNKNOWN:
|
||||
case UNKNOWNTYPE:
|
||||
if (isMaster)
|
||||
Error("[%s] console type unknown [%s:%d]",
|
||||
parserConsoleTemp->server, file, line);
|
||||
invalid = 1;
|
||||
break;
|
||||
}
|
||||
if (parserConsoleTemp->initsubst != (char *)0 &&
|
||||
parserConsoleTemp->initcmd != (char *)0) {
|
||||
if (parserConsoleTemp->port == 0 ||
|
||||
parserConsoleTemp->host == (char *)0) {
|
||||
if (parserConsoleTemp->port == 0) {
|
||||
if (isMaster)
|
||||
Error
|
||||
("[%s] console has 'initsubst' attribute without 'port' attribute (ignoring) [%s:%d]",
|
||||
parserConsoleTemp->server, file, line);
|
||||
}
|
||||
if (parserConsoleTemp->host == (char *)0) {
|
||||
if (isMaster)
|
||||
Error
|
||||
("[%s] console has 'initsubst' attribute without 'host' attribute (ignoring) [%s:%d]",
|
||||
parserConsoleTemp->server, file, line);
|
||||
}
|
||||
free(parserConsoleTemp->initsubst);
|
||||
parserConsoleTemp->initsubst = (char *)0;
|
||||
}
|
||||
}
|
||||
|
||||
if (invalid != 0) {
|
||||
DestroyParserDefaultOrConsole(parserConsoleTemp, (CONSENT **)0,
|
||||
@ -2139,109 +2422,6 @@ ExpandLogfile(c, id)
|
||||
OutOfMem();
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
DoSubstitution(char *sub, int port, char *host, char **string)
|
||||
#else
|
||||
DoSubstitution(sub, port, host, string)
|
||||
char *sub;
|
||||
int port;
|
||||
char *host;
|
||||
char **string;
|
||||
#endif
|
||||
{
|
||||
char *p = (char *)0;
|
||||
char *pstr = (char *)0;
|
||||
int o = 0;
|
||||
int i = 0;
|
||||
int plen = 0;
|
||||
int base = 0;
|
||||
short padzero = 0;
|
||||
STRING *result = (STRING *)0;
|
||||
|
||||
if (sub == (char *)0 || sub[0] == '\000' || sub[1] == '\000' ||
|
||||
string == (char **)0 || *string == (char *)0 || host == (char *)0)
|
||||
return;
|
||||
if (result == (STRING *)0)
|
||||
result = AllocString();
|
||||
BuildString((char *)0, result);
|
||||
|
||||
/* check the pattern for a length and padding */
|
||||
for (p = sub + 2; *p != '\000'; p++)
|
||||
if (!isdigit((int)(*p)))
|
||||
break;
|
||||
if (p != sub + 2) {
|
||||
plen = atoi(sub + 2);
|
||||
padzero = (sub[2] == '0');
|
||||
}
|
||||
|
||||
/* check for base */
|
||||
switch (*p) {
|
||||
case 'd':
|
||||
base = 10;
|
||||
break;
|
||||
case 'x':
|
||||
case 'X':
|
||||
base = 16;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
while (port >= base) {
|
||||
if (port % base >= 10)
|
||||
BuildStringChar((port % base) - 10 + (*p == 'x' ? 'a' : 'A'),
|
||||
result);
|
||||
else
|
||||
BuildStringChar((port % base) + '0', result);
|
||||
port /= base;
|
||||
}
|
||||
if (port >= 10)
|
||||
BuildStringChar(port - 10 + (*p == 'x' ? 'a' : 'A'), result);
|
||||
else
|
||||
BuildStringChar(port + '0', result);
|
||||
|
||||
/* if we're supposed to be a certain length, pad it */
|
||||
while (result->used - 1 < plen) {
|
||||
if (padzero == 0)
|
||||
BuildStringChar(' ', result);
|
||||
else
|
||||
BuildStringChar('0', result);
|
||||
}
|
||||
|
||||
/* reverse the text to put it in forward order */
|
||||
o = result->used - 1;
|
||||
for (i = 0; i < o / 2; i++) {
|
||||
char temp;
|
||||
|
||||
temp = result->string[i];
|
||||
result->string[i]
|
||||
= result->string[o - i - 1];
|
||||
result->string[o - i - 1] = temp;
|
||||
}
|
||||
if ((pstr = StrDup(result->string)) == (char *)0)
|
||||
OutOfMem();
|
||||
|
||||
BuildString((char *)0, result);
|
||||
for (o = 0, p = *string; *(p + o) != '\000'; o++) {
|
||||
if (*(p + o) == sub[0]) {
|
||||
BuildStringN(p, o, result);
|
||||
BuildString(host, result);
|
||||
p += o + 1;
|
||||
o = -1;
|
||||
} else if (*(p + o) == sub[1]) {
|
||||
BuildStringN(p, o, result);
|
||||
BuildString(pstr, result);
|
||||
p += o + 1;
|
||||
o = -1;
|
||||
}
|
||||
}
|
||||
BuildStringN(p, o, result);
|
||||
free(*string);
|
||||
if ((*string = StrDup(result->string)) == (char *)0)
|
||||
OutOfMem();
|
||||
free(pstr);
|
||||
}
|
||||
|
||||
/* this will adjust parserConsoles/parserConsolesTail if we're adding
|
||||
* a new console.
|
||||
*/
|
||||
@ -2616,21 +2796,27 @@ ConsoleAdd(c)
|
||||
SwapStr(&pCEmatch->host, &c->host);
|
||||
closeMatch = 0;
|
||||
}
|
||||
if (pCEmatch->port != c->port) {
|
||||
pCEmatch->port = c->port;
|
||||
if (pCEmatch->netport != c->netport) {
|
||||
pCEmatch->netport = c->netport;
|
||||
closeMatch = 0;
|
||||
}
|
||||
break;
|
||||
case UNKNOWN:
|
||||
case UNKNOWNTYPE:
|
||||
break;
|
||||
}
|
||||
|
||||
/* and now the rest (minus the "runtime" members - see below) */
|
||||
pCEmatch->idletimeout = c->idletimeout;
|
||||
if (pCEmatch->idletimeout != (time_t)0 &&
|
||||
(timers[T_IDLE] == (time_t)0 ||
|
||||
timers[T_IDLE] > pCEmatch->lastWrite + pCEmatch->idletimeout))
|
||||
timers[T_IDLE] = pCEmatch->lastWrite + pCEmatch->idletimeout;
|
||||
(timers[T_CIDLE] == (time_t)0 ||
|
||||
timers[T_CIDLE] >
|
||||
pCEmatch->lastWrite + pCEmatch->idletimeout))
|
||||
timers[T_CIDLE] = pCEmatch->lastWrite + pCEmatch->idletimeout;
|
||||
|
||||
pCEmatch->logfilemax = c->logfilemax;
|
||||
if (pCEmatch->logfilemax != (off_t) 0 &&
|
||||
timers[T_ROLL] == (time_t)0)
|
||||
timers[T_ROLL] = time((time_t)0);
|
||||
|
||||
SwapStr(&pCEmatch->motd, &c->motd);
|
||||
SwapStr(&pCEmatch->idlestring, &c->idlestring);
|
||||
@ -2722,25 +2908,46 @@ ConsoleDestroy()
|
||||
if (c->breakNum == 0)
|
||||
c->breakNum = 1;
|
||||
|
||||
/* portbase and portinc values are +1 so a zero can show that
|
||||
* no value was given. defaults: portbase=0, portinc=1
|
||||
/* portbase, portinc, and port values are +2, +1, +1, so a zero can
|
||||
* show that no value was given. defaults: portbase=0, portinc=1
|
||||
*/
|
||||
if (c->portbase != 0)
|
||||
c->portbase--;
|
||||
c->portbase -= 2;
|
||||
if (c->portinc != 0)
|
||||
c->portinc--;
|
||||
else
|
||||
c->portinc = 1;
|
||||
|
||||
/* if this is ever false, we don't actually use the port value, so
|
||||
* doesn't matter if we "default" to zero...it's all enforced in
|
||||
* ConsoleEnd()
|
||||
*/
|
||||
if (c->port != 0)
|
||||
c->port--;
|
||||
|
||||
/* now calculate the "real" port number */
|
||||
c->port = c->portbase + c->portinc * c->port;
|
||||
|
||||
/* this formula could give -1 because
|
||||
* portbase >= -1, portinc >= 0, and port >= 0
|
||||
* since it's an unsigned type, it'll wrap back around
|
||||
* look very, very, bizarre. but, oh well. yeah, a
|
||||
* user can shoot himself in the foot with a bad config
|
||||
* file, but it won't hurt too much.
|
||||
*/
|
||||
c->netport = c->portbase + c->portinc * c->port;
|
||||
|
||||
/* check for substitutions */
|
||||
if (c->type == DEVICE && c->devicesubst != (char *)0)
|
||||
DoSubstitution(c->devicesubst, c->port, c->host, &(c->device));
|
||||
ProcessSubst(c, &(c->device), (char **)0, (char *)0,
|
||||
c->devicesubst);
|
||||
|
||||
if (c->type == EXEC && c->execsubst != (char *)0)
|
||||
DoSubstitution(c->execsubst, c->port, c->host, &(c->exec));
|
||||
ProcessSubst(c, &(c->exec), (char **)0, (char *)0,
|
||||
c->execsubst);
|
||||
|
||||
if (c->initcmd != (char *)0 && c->initsubst != (char *)0)
|
||||
ProcessSubst(c, &(c->initcmd), (char **)0, (char *)0,
|
||||
c->initsubst);
|
||||
|
||||
/* go ahead and do the '&' substitution */
|
||||
if (c->logfile != (char *)0) {
|
||||
@ -2805,6 +3012,48 @@ ConsoleDestroy()
|
||||
|
||||
/* now remember where we're headed and do the dirty work */
|
||||
cNext = c->pCEnext;
|
||||
if (fSyntaxOnly > 1) {
|
||||
static STRING *s = (STRING *)0;
|
||||
|
||||
if (s == (STRING *)0)
|
||||
s = AllocString();
|
||||
|
||||
BuildString((char *)0, s);
|
||||
BuildString(BuildTmpStringPrint
|
||||
("{%s:%s:", c->server, c->master), s);
|
||||
if (c->aliases != (NAMES *)0) {
|
||||
NAMES *n;
|
||||
for (n = c->aliases; n != (NAMES *)0; n = n->next) {
|
||||
if (n == c->aliases)
|
||||
BuildStringChar(',', s);
|
||||
BuildString(n->name, s);
|
||||
}
|
||||
}
|
||||
BuildStringChar(':', s);
|
||||
switch (c->type) {
|
||||
case EXEC:
|
||||
BuildString(BuildTmpStringPrint
|
||||
("|:%s",
|
||||
(c->exec !=
|
||||
(char *)0 ? c->exec : "/bin/sh")), s);
|
||||
break;
|
||||
case HOST:
|
||||
BuildString(BuildTmpStringPrint
|
||||
("!:%s,%hu", c->host, c->netport), s);
|
||||
break;
|
||||
case DEVICE:
|
||||
BuildString(BuildTmpStringPrint
|
||||
("/:%s,%s%c", c->device,
|
||||
(c->baud ? c->baud->acrate : ""),
|
||||
(c->parity ? c->parity->key[0] : ' ')),
|
||||
s);
|
||||
break;
|
||||
case UNKNOWNTYPE: /* shut up gcc */
|
||||
break;
|
||||
}
|
||||
BuildStringChar('}', s);
|
||||
Msg("%s", s->string);
|
||||
}
|
||||
ConsoleAdd(c);
|
||||
}
|
||||
|
||||
@ -2999,7 +3248,8 @@ ConsoleItemDevicesubst(id)
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "ConsoleItemDevicesubst(%s) [%s:%d]", id, file, line));
|
||||
ProcessDevicesubst(parserConsoleTemp, id);
|
||||
ProcessSubst((CONSENT *)0, (char **)0,
|
||||
&(parserConsoleTemp->devicesubst), "devicesubst", id);
|
||||
}
|
||||
|
||||
void
|
||||
@ -3011,7 +3261,21 @@ ConsoleItemExecsubst(id)
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "ConsoleItemExecsubst(%s) [%s:%d]", id, file, line));
|
||||
ProcessExecsubst(parserConsoleTemp, id);
|
||||
ProcessSubst((CONSENT *)0, (char **)0, &(parserConsoleTemp->execsubst),
|
||||
"execsubst", id);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ConsoleItemInitsubst(char *id)
|
||||
#else
|
||||
ConsoleItemInitsubst(id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "ConsoleItemInitsubst(%s) [%s:%d]", id, file, line));
|
||||
ProcessSubst((CONSENT *)0, (char **)0, &(parserConsoleTemp->initsubst),
|
||||
"initsubst", id);
|
||||
}
|
||||
|
||||
void
|
||||
@ -3074,6 +3338,18 @@ ConsoleItemLogfile(id)
|
||||
ProcessLogfile(parserConsoleTemp, id);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ConsoleItemLogfilemax(char *id)
|
||||
#else
|
||||
ConsoleItemLogfilemax(id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "ConsoleItemLogfilemax(%s) [%s:%d]", id, file, line));
|
||||
ProcessLogfilemax(parserConsoleTemp, id);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ConsoleItemInitcmd(char *id)
|
||||
@ -3182,6 +3458,18 @@ ConsoleItemPortinc(id)
|
||||
ProcessPortinc(parserConsoleTemp, id);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ConsoleItemProtocol(char *id)
|
||||
#else
|
||||
ConsoleItemProtocol(id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "ConsoleItemProtocol(%s) [%s:%d]", id, file, line));
|
||||
ProcessProtocol(parserConsoleTemp, id);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ConsoleItemIdletimeout(char *id)
|
||||
@ -4158,7 +4446,9 @@ ITEM keyDefault[] = {
|
||||
{"idletime", DefaultItemIdletimeout},
|
||||
{"include", DefaultItemInclude},
|
||||
{"initcmd", DefaultItemInitcmd},
|
||||
{"initsubst", DefaultItemInitsubst},
|
||||
{"logfile", DefaultItemLogfile},
|
||||
{"logfilemax", DefaultItemLogfilemax},
|
||||
{"master", DefaultItemMaster},
|
||||
{"motd", DefaultItemMOTD},
|
||||
{"options", DefaultItemOptions},
|
||||
@ -4166,6 +4456,7 @@ ITEM keyDefault[] = {
|
||||
{"port", DefaultItemPort},
|
||||
{"portbase", DefaultItemPortbase},
|
||||
{"portinc", DefaultItemPortinc},
|
||||
{"protocol", DefaultItemProtocol},
|
||||
{"ro", DefaultItemRo},
|
||||
{"rw", DefaultItemRw},
|
||||
{"timestamp", DefaultItemTimestamp},
|
||||
@ -4187,7 +4478,9 @@ ITEM keyConsole[] = {
|
||||
{"idletimeout", ConsoleItemIdletimeout},
|
||||
{"include", ConsoleItemInclude},
|
||||
{"initcmd", ConsoleItemInitcmd},
|
||||
{"initsubst", ConsoleItemInitsubst},
|
||||
{"logfile", ConsoleItemLogfile},
|
||||
{"logfilemax", ConsoleItemLogfilemax},
|
||||
{"master", ConsoleItemMaster},
|
||||
{"motd", ConsoleItemMOTD},
|
||||
{"options", ConsoleItemOptions},
|
||||
@ -4195,6 +4488,7 @@ ITEM keyConsole[] = {
|
||||
{"port", ConsoleItemPort},
|
||||
{"portbase", ConsoleItemPortbase},
|
||||
{"portinc", ConsoleItemPortinc},
|
||||
{"protocol", ConsoleItemProtocol},
|
||||
{"ro", ConsoleItemRo},
|
||||
{"rw", ConsoleItemRw},
|
||||
{"timestamp", ConsoleItemTimestamp},
|
||||
@ -4422,7 +4716,7 @@ ReadCfg(filename, fp)
|
||||
#endif
|
||||
isStartup = (pGroups == (GRPENT *)0 && pRCList == (REMOTE *)0);
|
||||
|
||||
/* inititalize local things */
|
||||
/* initialize local things */
|
||||
if (word == (STRING *)0)
|
||||
word = AllocString();
|
||||
line = 1;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: version.h,v 1.53 2003/11/20 14:15:39 bryan Exp $
|
||||
* $Id: version.h,v 1.59 2004/03/16 04:17:31 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -14,4 +14,4 @@
|
||||
@(#) Copyright 2000 conserver.com.\n\
|
||||
All rights reserved.\n"
|
||||
|
||||
#define THIS_VERSION "conserver.com version 8.0.7"
|
||||
#define THIS_VERSION "conserver.com version 8.1.3"
|
||||
|
@ -15,7 +15,7 @@ MKDIR = @MKDIR@
|
||||
|
||||
### Compiler and link options
|
||||
CC = @CC@
|
||||
CFLAGS = @CFLAGS@ # -DPUCC -DSUN5
|
||||
CFLAGS = @CFLAGS@
|
||||
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)\"
|
||||
CPPFLAGS = -I.. -I$(top_srcdir) -I$(srcdir) -I$(top_srcdir)/conserver $(DEFS) @CPPFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
@ -26,17 +26,22 @@ LIBS = @LIBS@
|
||||
### Makefile rules - no user-servicable parts below
|
||||
|
||||
CONSOLE_OBJS = console.o getpassword.o ../conserver/cutil.o
|
||||
CONSOLE_HDRS = ../config.h $(top_srcdir)/compat.h $(top_srcdir)/conserver/port.h
|
||||
CONSOLE_HDRS = ../config.h $(top_srcdir)/compat.h \
|
||||
$(top_srcdir)/conserver/cutil.h \
|
||||
$(top_srcdir)/conserver/version.h \
|
||||
$(srcdir)/getpassword.h
|
||||
ALL = console
|
||||
|
||||
|
||||
all: $(ALL)
|
||||
|
||||
$(CONSOLE_OBJS): $(CONSOLE_HDRS)
|
||||
|
||||
console: $(CONSOLE_OBJS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o console $(CONSOLE_OBJS) $(LIBS)
|
||||
|
||||
../conserver/util.o:
|
||||
( cd ../conserver && $(MAKE) $(MAKE_FLAGS) util.o ) || exit 1;
|
||||
../conserver/cutil.o:
|
||||
( cd ../conserver && $(MAKE) $(MAKE_FLAGS) cutil.o ) || exit 1;
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: console.c,v 5.151 2003/11/20 13:56:41 bryan Exp $
|
||||
* $Id: console.c,v 5.161 2004/03/20 14:40:42 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -54,6 +54,13 @@ unsigned short bindPort;
|
||||
CONSFILE *cfstdout;
|
||||
char *pcUser = (char *)0;
|
||||
int disconnectCount = 0;
|
||||
STRING *execCmd = (STRING *)0;
|
||||
CONSFILE *execCmdFile = (CONSFILE *)0;
|
||||
pid_t execCmdPid = 0;
|
||||
CONSFILE *gotoConsole = (CONSFILE *)0;
|
||||
CONSFILE *prevConsole = (CONSFILE *)0;
|
||||
char *gotoName = (char *)0;
|
||||
char *prevName = (char *)0;
|
||||
|
||||
#if HAVE_OPENSSL
|
||||
SSL_CTX *ctx = (SSL_CTX *)0;
|
||||
@ -190,7 +197,7 @@ Usage(wantfull)
|
||||
"D enable debug output, sent to stderr",
|
||||
"e esc set the initial escape characters",
|
||||
#if HAVE_OPENSSL
|
||||
"E don't require encrypted connections",
|
||||
"E don't attempt encrypted connections",
|
||||
#else
|
||||
"E ignored - encryption not compiled into code",
|
||||
#endif
|
||||
@ -549,6 +556,9 @@ DestroyDataStructures()
|
||||
#endif
|
||||
{
|
||||
C2Cooked();
|
||||
if (cfstdout != (CONSFILE *)0)
|
||||
FileUnopen(cfstdout);
|
||||
DestroyStrings();
|
||||
}
|
||||
|
||||
char *
|
||||
@ -570,6 +580,7 @@ ReadReply(fd)
|
||||
BuildString((char *)0, result);
|
||||
|
||||
while (1) {
|
||||
int l;
|
||||
switch (nr = FileRead(fd, buf, sizeof(buf))) {
|
||||
case 0:
|
||||
/* fall through */
|
||||
@ -580,6 +591,13 @@ ReadReply(fd)
|
||||
Error("lost connection");
|
||||
Bye(EX_UNAVAILABLE);
|
||||
default:
|
||||
while ((l = ParseIACBuf(fd, buf, &nr)) >= 0) {
|
||||
if (l == 0)
|
||||
continue;
|
||||
BuildStringN(buf, l, result);
|
||||
nr -= l;
|
||||
MemMove(buf, buf + l, nr);
|
||||
}
|
||||
BuildStringN(buf, nr, result);
|
||||
if (toEOF) /* if toEOF, read until EOF */
|
||||
continue;
|
||||
@ -601,84 +619,492 @@ ReadReply(fd)
|
||||
return result->string;
|
||||
}
|
||||
|
||||
static int SawUrg = 0;
|
||||
|
||||
/* when the conserver program gets the suspend sequence it will send us
|
||||
* an out of band command to suspend ourself. We just tell the reader
|
||||
* routine we saw one
|
||||
*/
|
||||
RETSIGTYPE
|
||||
static void
|
||||
#if PROTOTYPES
|
||||
OOB(int sig)
|
||||
ReapVirt(void)
|
||||
#else
|
||||
OOB(sig)
|
||||
ReapVirt()
|
||||
#endif
|
||||
{
|
||||
pid_t pid;
|
||||
int UWbuf;
|
||||
|
||||
while (-1 != (pid = waitpid(-1, &UWbuf, WNOHANG | WUNTRACED))) {
|
||||
if (0 == pid)
|
||||
break;
|
||||
|
||||
/* stopped child is just continued
|
||||
*/
|
||||
if (WIFSTOPPED(UWbuf) && 0 == kill(pid, SIGCONT)) {
|
||||
Msg("child pid %lu: stopped, sending SIGCONT",
|
||||
(unsigned long)pid);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (WIFEXITED(UWbuf))
|
||||
Verbose("child process %lu: exit(%d)", pid,
|
||||
WEXITSTATUS(UWbuf));
|
||||
if (WIFSIGNALED(UWbuf))
|
||||
Verbose("child process %lu: signal(%d)", pid, WTERMSIG(UWbuf));
|
||||
if (pid == execCmdPid) {
|
||||
if (WIFEXITED(UWbuf))
|
||||
FilePrint(cfstdout, FLAGFALSE,
|
||||
"[local command terminated - pid %lu: exit(%d)]\r\n",
|
||||
pid, WEXITSTATUS(UWbuf));
|
||||
if (WIFSIGNALED(UWbuf))
|
||||
FilePrint(cfstdout, FLAGFALSE,
|
||||
"[local command terminated - pid %lu: signal(%d)]\r\n",
|
||||
pid, WTERMSIG(UWbuf));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static sig_atomic_t fSawReapVirt = 0;
|
||||
|
||||
#if HAVE_SIGACTION
|
||||
static
|
||||
#endif
|
||||
RETSIGTYPE
|
||||
#if PROTOTYPES
|
||||
FlagReapVirt(int sig)
|
||||
#else
|
||||
FlagReapVirt(sig)
|
||||
int sig;
|
||||
#endif
|
||||
{
|
||||
++SawUrg;
|
||||
fSawReapVirt = 1;
|
||||
#if !HAVE_SIGACTION
|
||||
#if defined(SIGURG)
|
||||
SimpleSignal(SIGURG, OOB);
|
||||
SimpleSignal(SIGCHLD, FlagReapVirt);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* invoke the execcmd command */
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ExecCmd(void)
|
||||
#else
|
||||
ExecCmd()
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
pid_t iNewGrp;
|
||||
extern char **environ;
|
||||
int pin[2];
|
||||
int pout[2];
|
||||
static char *apcArgv[] = {
|
||||
"/bin/sh", "-ce", (char *)0, (char *)0
|
||||
};
|
||||
|
||||
if (execCmd == (STRING *)0 || execCmd->used <= 1)
|
||||
return;
|
||||
|
||||
CONDDEBUG((1, "ExecCmd(): `%s'", execCmd->string));
|
||||
|
||||
/* pin[0] = parent read, pin[1] = child write */
|
||||
if (pipe(pin) != 0) {
|
||||
Error("ExecCmd(): pipe(): %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
/* pout[0] = child read, pout[l] = parent write */
|
||||
if (pipe(pout) != 0) {
|
||||
close(pin[0]);
|
||||
close(pin[1]);
|
||||
Error("ExecCmd(): pipe(): %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
switch (execCmdPid = fork()) {
|
||||
case -1:
|
||||
return;
|
||||
case 0:
|
||||
thepid = getpid();
|
||||
break;
|
||||
default:
|
||||
close(pout[0]);
|
||||
close(pin[1]);
|
||||
if ((execCmdFile =
|
||||
FileOpenPipe(pin[0], pout[1])) == (CONSFILE *)0) {
|
||||
Error("ExecCmd(): FileOpenPipe(%d,%d) failed", pin[0],
|
||||
pout[1]);
|
||||
close(pin[0]);
|
||||
close(pout[1]);
|
||||
kill(execCmdPid, SIGHUP);
|
||||
return;
|
||||
}
|
||||
FilePrint(cfstdout, FLAGFALSE,
|
||||
"[local command running - pid %lu]\r\n", execCmdPid);
|
||||
FD_SET(pin[0], &rinit);
|
||||
if (maxfd < pin[0] + 1)
|
||||
maxfd = pin[0] + 1;
|
||||
fflush(stderr);
|
||||
return;
|
||||
}
|
||||
|
||||
close(pin[0]);
|
||||
close(pout[1]);
|
||||
|
||||
/* put the signals back that we ignore (trapped auto-reset to default)
|
||||
*/
|
||||
SimpleSignal(SIGPIPE, SIG_DFL);
|
||||
SimpleSignal(SIGCHLD, SIG_DFL);
|
||||
|
||||
/* setup new process with clean file descriptors
|
||||
* stderr still goes to stderr...so user sees it
|
||||
*/
|
||||
i = GetMaxFiles();
|
||||
for ( /* i above */ ; --i > 3;) {
|
||||
if (i != pout[0] && i != pin[1])
|
||||
close(i);
|
||||
}
|
||||
close(1);
|
||||
close(0);
|
||||
|
||||
# if HAVE_SETSID
|
||||
iNewGrp = setsid();
|
||||
if (-1 == iNewGrp) {
|
||||
Error("ExecCmd(): setsid(): %s", strerror(errno));
|
||||
iNewGrp = thepid;
|
||||
}
|
||||
# else
|
||||
iNewGrp = thepid;
|
||||
# endif
|
||||
|
||||
if (dup(pout[0]) != 0 || dup(pin[1]) != 1) {
|
||||
Error("ExecCmd(): fd sync error");
|
||||
Bye(EX_OSERR);
|
||||
}
|
||||
close(pout[0]);
|
||||
close(pin[1]);
|
||||
|
||||
tcsetpgrp(0, iNewGrp);
|
||||
|
||||
apcArgv[2] = execCmd->string;
|
||||
|
||||
execve(apcArgv[0], apcArgv, environ);
|
||||
Error("ExecCmd(): execve(%s): %s", apcArgv[2], strerror(errno));
|
||||
Bye(EX_OSERR);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ProcessUrgentData(int s)
|
||||
GetUserInput(STRING *str)
|
||||
#else
|
||||
ProcessUrgentData(s)
|
||||
int s;
|
||||
GetUserInput(str)
|
||||
STRING *str;
|
||||
#endif
|
||||
{
|
||||
static char acCmd;
|
||||
char c;
|
||||
|
||||
SawUrg = 0;
|
||||
if (str == (STRING *)0)
|
||||
return;
|
||||
|
||||
/* get the pending urgent message
|
||||
*/
|
||||
while (recv(s, &acCmd, 1, MSG_OOB) < 0) {
|
||||
switch (errno) {
|
||||
case EWOULDBLOCK:
|
||||
/* clear any pending input to make room */
|
||||
read(s, &acCmd, 1);
|
||||
write(1, ".", 1);
|
||||
continue;
|
||||
case EINVAL:
|
||||
default:
|
||||
Error("recv(%d): %s\r", s, strerror(errno));
|
||||
sleep(1);
|
||||
continue;
|
||||
BuildString((char *)0, str);
|
||||
|
||||
for (;;) {
|
||||
if (read(0, &c, 1) == 0)
|
||||
break;
|
||||
if (c == '\n' || c == '\r') {
|
||||
break;
|
||||
}
|
||||
if (c >= ' ' && c <= '~') {
|
||||
BuildStringChar(c, str);
|
||||
FileWrite(cfstdout, FLAGFALSE, &c, 1);
|
||||
} else if ((c == '\b' || c == 0x7f) && str->used > 1) {
|
||||
FileWrite(cfstdout, FLAGFALSE, "\b \b", 3);
|
||||
str->string[str->used - 2] = '\000';
|
||||
str->used--;
|
||||
} else if ((c == 0x15) && str->used > 1) {
|
||||
while (str->used > 1) {
|
||||
FileWrite(cfstdout, FLAGFALSE, "\b \b", 3);
|
||||
str->string[str->used - 2] = '\000';
|
||||
str->used--;
|
||||
}
|
||||
} else if ((c == 0x17) && str->used > 1) {
|
||||
while (str->used > 1 &&
|
||||
isspace((int)(str->string[str->used - 2]))) {
|
||||
FileWrite(cfstdout, FLAGFALSE, "\b \b", 3);
|
||||
str->string[str->used - 2] = '\000';
|
||||
str->used--;
|
||||
}
|
||||
while (str->used > 1 &&
|
||||
!isspace((int)(str->string[str->used - 2]))) {
|
||||
FileWrite(cfstdout, FLAGFALSE, "\b \b", 3);
|
||||
str->string[str->used - 2] = '\000';
|
||||
str->used--;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (acCmd) {
|
||||
case OB_SUSP:
|
||||
#if defined(SIGSTOP)
|
||||
write(1, "stop]", 5);
|
||||
C2Cooked();
|
||||
kill(getpid(), SIGSTOP);
|
||||
C2Raw();
|
||||
write(1, "[press any character to continue", 32);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
DoExec(CONSFILE *pcf)
|
||||
#else
|
||||
write(1,
|
||||
"stop not supported -- press any character to continue",
|
||||
53);
|
||||
DoExec(pcf)
|
||||
CONSFILE *pcf;
|
||||
#endif
|
||||
break;
|
||||
case OB_DROP:
|
||||
write(1, "dropped by server]\r\n", 20);
|
||||
C2Cooked();
|
||||
Bye(EX_UNAVAILABLE);
|
||||
/*NOTREACHED*/ default:
|
||||
Error("unknown out of band command `%c\'\r", acCmd);
|
||||
fflush(stderr);
|
||||
break;
|
||||
{
|
||||
FileWrite(cfstdout, FLAGFALSE, "exec: ", 6);
|
||||
|
||||
GetUserInput(execCmd);
|
||||
FileWrite(cfstdout, FLAGFALSE, "]\r\n", 3);
|
||||
|
||||
if (execCmd != (STRING *)0 && execCmd->used > 1) {
|
||||
ExecCmd();
|
||||
BuildString((char *)0, execCmd);
|
||||
if (execCmdFile == (CONSFILE *)0) { /* exec failed */
|
||||
/* say forget it */
|
||||
FileSetQuoteIAC(pcf, FLAGFALSE);
|
||||
FilePrint(pcf, FLAGFALSE, "%c%c", OB_IAC, OB_ABRT);
|
||||
FileSetQuoteIAC(pcf, FLAGTRUE);
|
||||
} else {
|
||||
char *r;
|
||||
/* go back to blocking mode */
|
||||
SetFlags(FileFDNum(pcf), 0, O_NONBLOCK);
|
||||
/* say we're ready */
|
||||
FileSetQuoteIAC(pcf, FLAGFALSE);
|
||||
FilePrint(pcf, FLAGFALSE, "%c%c", OB_IAC, OB_EXEC);
|
||||
FileSetQuoteIAC(pcf, FLAGTRUE);
|
||||
r = ReadReply(pcf, 0);
|
||||
/* now back to non-blocking, now that we've got reply */
|
||||
SetFlags(FileFDNum(pcf), O_NONBLOCK, 0);
|
||||
/* if we aren't still r/w, abort */
|
||||
if (strncmp(r, "[rw]", 4) != 0) {
|
||||
FileWrite(cfstdout, FLAGFALSE,
|
||||
"[no longer read-write - aborting command]\r\n",
|
||||
-1);
|
||||
FD_CLR(FileFDNum(execCmdFile), &rinit);
|
||||
FD_CLR(FileFDOutNum(execCmdFile), &winit);
|
||||
FileClose(&execCmdFile);
|
||||
FileSetQuoteIAC(pcf, FLAGFALSE);
|
||||
FilePrint(pcf, FLAGFALSE, "%c%c", OB_IAC, OB_ABRT);
|
||||
FileSetQuoteIAC(pcf, FLAGTRUE);
|
||||
kill(execCmdPid, SIGHUP);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* say forget it */
|
||||
FileSetQuoteIAC(pcf, FLAGFALSE);
|
||||
FilePrint(pcf, FLAGFALSE, "%c%c", OB_IAC, OB_ABRT);
|
||||
FileSetQuoteIAC(pcf, FLAGTRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
Interact(CONSFILE *pcf, char *pcMach)
|
||||
#else
|
||||
Interact(pcf, pcMach)
|
||||
CONSFILE *pcf;
|
||||
char *pcMach;
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
int nc;
|
||||
fd_set rmask, wmask;
|
||||
int justSuspended = 0;
|
||||
static char acMesg[8192];
|
||||
|
||||
/* if this is true, it means we successfully moved to a new console
|
||||
* so we need to close the old one.
|
||||
*/
|
||||
if (prevConsole != (CONSFILE *)0)
|
||||
FileClose(&prevConsole);
|
||||
if (prevName != (char *)0) {
|
||||
free(prevName);
|
||||
prevName = (char *)0;
|
||||
}
|
||||
|
||||
/* this is only true in other parts of the code iff pcf == gotoConsole */
|
||||
if (gotoConsole != (CONSFILE *)0) {
|
||||
gotoConsole = (CONSFILE *)0;
|
||||
FilePrint(cfstdout, FLAGFALSE, "[returning to `%s'", pcMach);
|
||||
FileWrite(pcf, FLAGFALSE, "\n", 1);
|
||||
}
|
||||
|
||||
C2Raw();
|
||||
|
||||
/* set socket to non-blocking */
|
||||
SetFlags(FileFDNum(pcf), O_NONBLOCK, 0);
|
||||
|
||||
/* read from stdin and the socket (non-blocking!).
|
||||
* rmask indicates which descriptors to read from,
|
||||
* the others are not used, nor is the result from
|
||||
* select, read, or write.
|
||||
*/
|
||||
FD_ZERO(&rinit);
|
||||
FD_ZERO(&winit);
|
||||
FD_SET(FileFDNum(pcf), &rinit);
|
||||
FD_SET(0, &rinit);
|
||||
if (maxfd < FileFDNum(pcf) + 1)
|
||||
maxfd = FileFDNum(pcf) + 1;
|
||||
for (;;) {
|
||||
justSuspended = 0;
|
||||
if (fSawReapVirt) {
|
||||
fSawReapVirt = 0;
|
||||
ReapVirt();
|
||||
}
|
||||
/* reset read mask and select on it
|
||||
*/
|
||||
rmask = rinit;
|
||||
wmask = winit;
|
||||
if (-1 ==
|
||||
select(maxfd, &rmask, &wmask, (fd_set *)0,
|
||||
(struct timeval *)0)) {
|
||||
if (errno != EINTR) {
|
||||
Error("Master(): select(): %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* anything from execCmd */
|
||||
if (execCmdFile != (CONSFILE *)0) {
|
||||
if (FileCanRead(execCmdFile, &rmask, &wmask)) {
|
||||
if ((nc =
|
||||
FileRead(execCmdFile, acMesg, sizeof(acMesg))) < 0) {
|
||||
FD_CLR(FileFDNum(execCmdFile), &rinit);
|
||||
FD_CLR(FileFDOutNum(execCmdFile), &winit);
|
||||
FileClose(&execCmdFile);
|
||||
FileSetQuoteIAC(pcf, FLAGFALSE);
|
||||
FilePrint(pcf, FLAGFALSE, "%c%c", OB_IAC, OB_ABRT);
|
||||
FileSetQuoteIAC(pcf, FLAGTRUE);
|
||||
} else {
|
||||
if (fStrip) {
|
||||
for (i = 0; i < nc; ++i)
|
||||
acMesg[i] &= 127;
|
||||
}
|
||||
FileWrite(pcf, FLAGFALSE, acMesg, nc);
|
||||
}
|
||||
} else if (!FileBufEmpty(execCmdFile) &&
|
||||
FileCanWrite(execCmdFile, &rmask, &wmask)) {
|
||||
CONDDEBUG((1, "Interact(): flushing fd %d",
|
||||
FileFDNum(execCmdFile)));
|
||||
if (FileWrite(execCmdFile, FLAGFALSE, (char *)0, 0) < 0) {
|
||||
/* -bryan */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* anything from socket? */
|
||||
if (FileCanRead(pcf, &rmask, &wmask)) {
|
||||
int l;
|
||||
if ((nc = FileRead(pcf, acMesg, sizeof(acMesg))) < 0) {
|
||||
/* if we got an error/eof after returning from suspend */
|
||||
if (justSuspended) {
|
||||
fprintf(stderr, "\n");
|
||||
Error("lost connection");
|
||||
}
|
||||
break;
|
||||
}
|
||||
while ((l = ParseIACBuf(pcf, acMesg, &nc)) >= 0) {
|
||||
if (l == 0) {
|
||||
if (execCmdFile == (CONSFILE *)0) {
|
||||
if (FileSawQuoteExec(pcf) == FLAGTRUE)
|
||||
DoExec(pcf);
|
||||
else if (FileSawQuoteSusp(pcf) == FLAGTRUE) {
|
||||
justSuspended = 1;
|
||||
#if defined(SIGSTOP)
|
||||
FileWrite(cfstdout, FLAGFALSE, "stop]", 5);
|
||||
C2Cooked();
|
||||
kill(thepid, SIGSTOP);
|
||||
C2Raw();
|
||||
FileWrite(cfstdout, FLAGFALSE,
|
||||
"[press any character to continue",
|
||||
32);
|
||||
#else
|
||||
FileWrite(cfstdout, FLAGFALSE,
|
||||
"stop not supported -- press any character to continue",
|
||||
53);
|
||||
#endif
|
||||
} else if (FileSawQuoteGoto(pcf) == FLAGTRUE) {
|
||||
gotoConsole = pcf;
|
||||
if (gotoName != (char *)0)
|
||||
free(gotoName);
|
||||
if ((gotoName = StrDup(pcMach)) == (char *)0)
|
||||
OutOfMem();
|
||||
C2Cooked();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (FileSawQuoteAbrt(pcf) == FLAGTRUE) {
|
||||
FD_CLR(FileFDNum(execCmdFile), &rinit);
|
||||
FD_CLR(FileFDOutNum(execCmdFile), &winit);
|
||||
FileClose(&execCmdFile);
|
||||
kill(execCmdPid, SIGHUP);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (fStrip) {
|
||||
for (i = 0; i < l; ++i)
|
||||
acMesg[i] &= 127;
|
||||
}
|
||||
FileWrite(cfstdout, FLAGFALSE, acMesg, l);
|
||||
if (execCmdFile != (CONSFILE *)0) {
|
||||
FileWrite(execCmdFile, FLAGFALSE, acMesg, l);
|
||||
}
|
||||
nc -= l;
|
||||
MemMove(acMesg, acMesg + l, nc);
|
||||
}
|
||||
} else if (!FileBufEmpty(pcf) && FileCanWrite(pcf, &rmask, &wmask)) {
|
||||
CONDDEBUG((1, "Interact(): flushing fd %d", FileFDNum(pcf)));
|
||||
if (FileWrite(pcf, FLAGFALSE, (char *)0, 0) < 0) {
|
||||
/* -bryan */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* anything from stdin? */
|
||||
if (FD_ISSET(0, &rmask)) {
|
||||
if ((nc = read(0, acMesg, sizeof(acMesg))) == 0) {
|
||||
if (screwy)
|
||||
break;
|
||||
else {
|
||||
FD_SET(0, &rinit);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (execCmdFile == (CONSFILE *)0) {
|
||||
if (fStrip) {
|
||||
for (i = 0; i < nc; ++i)
|
||||
acMesg[i] &= 127;
|
||||
}
|
||||
FileWrite(pcf, FLAGFALSE, acMesg, nc);
|
||||
} else {
|
||||
for (i = 0; i < nc; ++i) {
|
||||
if (acMesg[i] == '\n' || acMesg[i] == '\r')
|
||||
FilePrint(cfstdout, FLAGFALSE,
|
||||
"[local command running - pid %lu]\r\n",
|
||||
execCmdPid);
|
||||
else if (acMesg[i] == 0x03) { /* ctrl-c */
|
||||
kill(execCmdPid, SIGHUP);
|
||||
FilePrint(cfstdout, FLAGFALSE,
|
||||
"[local command sent SIGHUP - pid %lu]\r\n",
|
||||
execCmdPid);
|
||||
} else if (acMesg[i] == 0x1c) { /* ctrl-\ */
|
||||
kill(execCmdPid, SIGKILL);
|
||||
FilePrint(cfstdout, FLAGFALSE,
|
||||
"[local command sent SIGKILL - pid %lu]\r\n",
|
||||
execCmdPid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
C2Cooked();
|
||||
if (fVerbose)
|
||||
printf("Console %s closed.\n", pcMach);
|
||||
}
|
||||
|
||||
/* interact with a group server (ksb)
|
||||
*/
|
||||
static int
|
||||
void
|
||||
#if PROTOTYPES
|
||||
CallUp(CONSFILE *pcf, char *pcMaster, char *pcMach, char *pcHow,
|
||||
char *result)
|
||||
@ -688,22 +1114,17 @@ CallUp(pcf, pcMaster, pcMach, pcHow, result)
|
||||
char *pcMaster, *pcMach, *pcHow, *result;
|
||||
#endif
|
||||
{
|
||||
int nc;
|
||||
int fIn = '-';
|
||||
fd_set rmask, rinit;
|
||||
int i;
|
||||
int justProcessedUrg = 0;
|
||||
char *r = (char *)0;
|
||||
static char acMesg[8192];
|
||||
|
||||
if (fVerbose) {
|
||||
Msg("%s to %s (on %s)", pcHow, pcMach, pcMaster);
|
||||
}
|
||||
#if !defined(__CYGWIN__)
|
||||
# if defined(F_SETOWN)
|
||||
if (fcntl(FileFDNum(pcf), F_SETOWN, getpid()) == -1) {
|
||||
Error("fcntl(F_SETOWN,%d): %d: %s", getpid(), FileFDNum(pcf),
|
||||
strerror(errno));
|
||||
if (fcntl(FileFDNum(pcf), F_SETOWN, thepid) == -1) {
|
||||
Error("fcntl(F_SETOWN,%lu): %d: %s", (unsigned long)thepid,
|
||||
FileFDNum(pcf), strerror(errno));
|
||||
}
|
||||
# else
|
||||
# if defined(SIOCSPGRP)
|
||||
@ -711,7 +1132,7 @@ CallUp(pcf, pcMaster, pcMach, pcHow, result)
|
||||
int iTemp;
|
||||
/* on the HP-UX systems if different
|
||||
*/
|
||||
iTemp = -getpid();
|
||||
iTemp = -thepid;
|
||||
if (ioctl(FileFDNum(pcf), SIOCSPGRP, &iTemp) == -1) {
|
||||
Error("ioctl(%d,SIOCSPGRP): %s", FileFDNum(pcf),
|
||||
strerror(errno));
|
||||
@ -720,9 +1141,7 @@ CallUp(pcf, pcMaster, pcMach, pcHow, result)
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#if defined(SIGURG)
|
||||
SimpleSignal(SIGURG, OOB);
|
||||
#endif
|
||||
SimpleSignal(SIGCHLD, FlagReapVirt);
|
||||
|
||||
/* if we are going for a particular console
|
||||
* send sign-on stuff, then wait for some indication of what mode
|
||||
@ -816,75 +1235,7 @@ CallUp(pcf, pcMaster, pcMach, pcHow, result)
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
C2Raw();
|
||||
|
||||
/* read from stdin and the socket (non-blocking!).
|
||||
* rmask indicates which descriptors to read from,
|
||||
* the others are not used, nor is the result from
|
||||
* select, read, or write.
|
||||
*/
|
||||
FD_ZERO(&rinit);
|
||||
FD_SET(FileFDNum(pcf), &rinit);
|
||||
FD_SET(0, &rinit);
|
||||
if (maxfd < FileFDNum(pcf) + 1)
|
||||
maxfd = FileFDNum(pcf) + 1;
|
||||
for (;;) {
|
||||
justProcessedUrg = 0;
|
||||
if (SawUrg) {
|
||||
ProcessUrgentData(FileFDNum(pcf));
|
||||
justProcessedUrg = 1;
|
||||
}
|
||||
/* reset read mask and select on it
|
||||
*/
|
||||
rmask = rinit;
|
||||
if (-1 ==
|
||||
select(maxfd, &rmask, (fd_set *)0, (fd_set *)0,
|
||||
(struct timeval *)0)) {
|
||||
if (errno != EINTR) {
|
||||
Error("Master(): select(): %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* anything from socket? */
|
||||
if (FD_ISSET(FileFDNum(pcf), &rmask)) {
|
||||
if ((nc = FileRead(pcf, acMesg, sizeof(acMesg))) < 0) {
|
||||
/* if we got an error/eof after returning from suspend */
|
||||
if (justProcessedUrg) {
|
||||
fprintf(stderr, "\n");
|
||||
Error("lost connection");
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (fStrip) {
|
||||
for (i = 0; i < nc; ++i)
|
||||
acMesg[i] &= 127;
|
||||
}
|
||||
FileWrite(cfstdout, FLAGFALSE, acMesg, nc);
|
||||
}
|
||||
|
||||
/* anything from stdin? */
|
||||
if (FD_ISSET(0, &rmask)) {
|
||||
if ((nc = read(0, acMesg, sizeof(acMesg))) == 0) {
|
||||
if (screwy)
|
||||
break;
|
||||
else {
|
||||
FD_SET(0, &rinit);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (fStrip) {
|
||||
for (i = 0; i < nc; ++i)
|
||||
acMesg[i] &= 127;
|
||||
}
|
||||
FileWrite(pcf, FLAGFALSE, acMesg, nc);
|
||||
}
|
||||
}
|
||||
C2Cooked();
|
||||
if (fVerbose)
|
||||
printf("Console %s closed.\n", pcMach);
|
||||
return 0;
|
||||
Interact(pcf, pcMach);
|
||||
}
|
||||
|
||||
/* shouldn't need more than 3 levels of commands (but alloc 4 just 'cause)
|
||||
@ -902,11 +1253,11 @@ char *cmdarg = (char *)0;
|
||||
*/
|
||||
int
|
||||
#if PROTOTYPES
|
||||
DoCmds(char *master, char *ports, int cmdi)
|
||||
DoCmds(char *master, char *pports, int cmdi)
|
||||
#else
|
||||
DoCmds(master, ports, cmdi)
|
||||
DoCmds(master, pports, cmdi)
|
||||
char *master;
|
||||
char *ports;
|
||||
char *pports;
|
||||
int cmdi;
|
||||
#endif
|
||||
{
|
||||
@ -917,6 +1268,11 @@ DoCmds(master, ports, cmdi)
|
||||
unsigned short port;
|
||||
char *result = (char *)0;
|
||||
int len;
|
||||
char *ports;
|
||||
char *pcopy;
|
||||
|
||||
if ((pcopy = ports = StrDup(pports)) == (char *)0)
|
||||
OutOfMem();
|
||||
|
||||
len = strlen(ports);
|
||||
while (len > 0 && (ports[len - 1] == '\r' || ports[len - 1] == '\n'))
|
||||
@ -949,6 +1305,8 @@ DoCmds(master, ports, cmdi)
|
||||
if ((pcf = GetPort(server, port)) == (CONSFILE *)0)
|
||||
continue;
|
||||
|
||||
FileSetQuoteIAC(pcf, FLAGTRUE);
|
||||
|
||||
t = ReadReply(pcf, 0);
|
||||
if (strcmp(t, "ok\r\n") != 0) {
|
||||
FileClose(&pcf);
|
||||
@ -956,15 +1314,17 @@ DoCmds(master, ports, cmdi)
|
||||
continue;
|
||||
}
|
||||
#if HAVE_OPENSSL
|
||||
FileWrite(pcf, FLAGFALSE, "ssl\r\n", 5);
|
||||
t = ReadReply(pcf, 0);
|
||||
if (strcmp(t, "ok\r\n") == 0) {
|
||||
AttemptSSL(pcf);
|
||||
}
|
||||
if (fReqEncryption && FileGetType(pcf) != SSLSocket) {
|
||||
Error("Encryption not supported by server `%s'", server);
|
||||
FileClose(&pcf);
|
||||
continue;
|
||||
if (fReqEncryption) {
|
||||
FileWrite(pcf, FLAGFALSE, "ssl\r\n", 5);
|
||||
t = ReadReply(pcf, 0);
|
||||
if (strcmp(t, "ok\r\n") == 0) {
|
||||
AttemptSSL(pcf);
|
||||
}
|
||||
if (FileGetType(pcf) != SSLSocket) {
|
||||
Error("Encryption not supported by server `%s'", server);
|
||||
FileClose(&pcf);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1014,6 +1374,10 @@ DoCmds(master, ports, cmdi)
|
||||
continue;
|
||||
} else
|
||||
count = 0;
|
||||
} else if (strcmp(t, "ok\r\n") != 0) {
|
||||
FileClose(&pcf);
|
||||
FilePrint(cfstdout, FLAGFALSE, "%s: %s", server, t);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* now that we're logged in, we can do something */
|
||||
@ -1032,6 +1396,8 @@ DoCmds(master, ports, cmdi)
|
||||
if (cmdi != 0) {
|
||||
t = ReadReply(pcf, 0);
|
||||
/* save the result */
|
||||
if (result != (char *)0)
|
||||
free(result);
|
||||
if ((result = StrDup(t)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
@ -1050,13 +1416,10 @@ DoCmds(master, ports, cmdi)
|
||||
FileClose(&pcf);
|
||||
continue;
|
||||
} else {
|
||||
/* right now, we can only connect to one console, so it's ok
|
||||
* to clear the password. if we were allowed to connect to
|
||||
* multiple consoles (somehow), either in parallel or serial,
|
||||
* we wouldn't want to do this here */
|
||||
ClearPassword();
|
||||
CallUp(pcf, server, cmdarg, cmds[0], result);
|
||||
return 0;
|
||||
if (pcf != gotoConsole)
|
||||
FileClose(&pcf);
|
||||
break;
|
||||
}
|
||||
} else if (cmds[cmdi][0] == 'q') {
|
||||
t = ReadReply(pcf, 0);
|
||||
@ -1073,6 +1436,8 @@ DoCmds(master, ports, cmdi)
|
||||
if (cmdi == 0) {
|
||||
int len;
|
||||
/* if we hit bottom, this is where we get our results */
|
||||
if (result != (char *)0)
|
||||
free(result);
|
||||
if ((result = StrDup(t)) == (char *)0)
|
||||
OutOfMem();
|
||||
len = strlen(result);
|
||||
@ -1112,9 +1477,14 @@ DoCmds(master, ports, cmdi)
|
||||
DoCmds(server, result, cmdi);
|
||||
else if (cmdi > 0)
|
||||
DoCmds(server, result, cmdi - 1);
|
||||
free(result);
|
||||
if (result != (char *)0)
|
||||
free(result);
|
||||
result = (char *)0;
|
||||
}
|
||||
|
||||
if (result != (char *)0)
|
||||
free(result);
|
||||
free(pcopy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1145,12 +1515,14 @@ main(argc, argv)
|
||||
extern int optopt;
|
||||
extern char *optarg;
|
||||
int i;
|
||||
STRING *textMsg = (STRING *)0;
|
||||
static STRING *textMsg = (STRING *)0;
|
||||
int cmdi;
|
||||
int retval;
|
||||
static STRING *consoleName = (STRING *)0;
|
||||
|
||||
isMultiProc = 0; /* make sure stuff DOESN'T have the pid */
|
||||
|
||||
thepid = getpid();
|
||||
|
||||
if (textMsg == (STRING *)0)
|
||||
textMsg = AllocString();
|
||||
if (acPorts == (STRING *)0)
|
||||
@ -1330,7 +1702,8 @@ main(argc, argv)
|
||||
Error("missing console name");
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
cmdarg = argv[optind++];
|
||||
if ((cmdarg = StrDup(argv[optind++])) == (char *)0)
|
||||
OutOfMem();
|
||||
} else if (*pcCmd == 't') {
|
||||
if (optind >= argc) {
|
||||
Error("missing message text");
|
||||
@ -1387,6 +1760,8 @@ main(argc, argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (execCmd == (STRING *)0)
|
||||
execCmd = AllocString();
|
||||
|
||||
SimpleSignal(SIGPIPE, SIG_IGN);
|
||||
|
||||
@ -1416,12 +1791,54 @@ main(argc, argv)
|
||||
cmds[++cmdi] = "master";
|
||||
}
|
||||
|
||||
retval = DoCmds(pcInMaster, acPorts->string, cmdi);
|
||||
for (;;) {
|
||||
if (gotoConsole == (CONSFILE *)0)
|
||||
DoCmds(pcInMaster, acPorts->string, cmdi);
|
||||
else
|
||||
Interact(gotoConsole, gotoName);
|
||||
|
||||
/* if we didn't ask for another console, done */
|
||||
if (gotoConsole == (CONSFILE *)0 && prevConsole == (CONSFILE *)0)
|
||||
break;
|
||||
|
||||
if (consoleName == (STRING *)0)
|
||||
consoleName = AllocString();
|
||||
C2Raw();
|
||||
if (prevConsole == (CONSFILE *)0)
|
||||
FileWrite(cfstdout, FLAGFALSE, "console: ", 9);
|
||||
else
|
||||
FileWrite(cfstdout, FLAGFALSE, "[console: ", 10);
|
||||
GetUserInput(consoleName);
|
||||
FileWrite(cfstdout, FLAGFALSE, "]\r\n", 3);
|
||||
C2Cooked();
|
||||
if (consoleName->used > 1) {
|
||||
if (cmdarg != (char *)0)
|
||||
free(cmdarg);
|
||||
if ((cmdarg = StrDup(consoleName->string)) == (char *)0)
|
||||
OutOfMem();
|
||||
if (prevConsole == (CONSFILE *)0) {
|
||||
prevConsole = gotoConsole;
|
||||
gotoConsole = (CONSFILE *)0;
|
||||
prevName = gotoName;
|
||||
gotoName = (char *)0;
|
||||
}
|
||||
} else {
|
||||
if (prevConsole != (CONSFILE *)0) {
|
||||
gotoConsole = prevConsole;
|
||||
prevConsole = (CONSFILE *)0;
|
||||
gotoName = prevName;
|
||||
prevName = (char *)0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cmdarg != (char *)0)
|
||||
free(cmdarg);
|
||||
|
||||
if (*pcCmd == 'd')
|
||||
FilePrint(cfstdout, FLAGFALSE, "Disconnected %d users\n",
|
||||
disconnectCount);
|
||||
|
||||
Bye(retval);
|
||||
Bye(0);
|
||||
return 0; /* noop - Bye() terminates us */
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" $Id: console.man,v 1.40 2003/11/16 15:35:45 bryan Exp $
|
||||
.TH CONSOLE 1 "2003/11/16" "conserver-8.0.7" "conserver"
|
||||
.\" $Id: console.man,v 1.45 2004/03/20 14:40:42 bryan Exp $
|
||||
.TH CONSOLE 1 "2004/03/20" "conserver-8.1.3" "conserver"
|
||||
.SH NAME
|
||||
console \- console server client program
|
||||
.SH SYNOPSIS
|
||||
@ -318,13 +318,13 @@ a command, or `!' for a remote port.
|
||||
.TP
|
||||
.I console-details
|
||||
The details regarding the console.
|
||||
The values here (all comma separated) depend on the type of the console.
|
||||
Local devices will have values of the device file, baud rate, and
|
||||
The values here (all comma-separated) depend on the type of the console.
|
||||
Local devices will have values of the device file, baud rate/parity, and
|
||||
file descriptor for the device.
|
||||
Commands will have values of the command, the command's pid, the
|
||||
pseudo-tty, and file descriptor for the pseudo-tty.
|
||||
Remote ports will have values of the remote hostname, remote port number,
|
||||
and file descriptor for the socket connection.
|
||||
``raw'' or ``telnet'' protocol, and file descriptor for the socket connection.
|
||||
.TP
|
||||
.I users-list
|
||||
The details of each user connected to the console.
|
||||
@ -347,7 +347,7 @@ that the server can open the file for read, but not write.
|
||||
.TP
|
||||
.I logfile-details
|
||||
The details regarding the logging for the console.
|
||||
The comma separated
|
||||
The comma-separated
|
||||
values will be the logfile, ``log'' or ``nolog'' (if logging is on
|
||||
or not - toggled via ^EcL), ``act'' or ``noact'' (if activity logging is
|
||||
enabled or not - the `a' timestamp option), the timestamp interval, and
|
||||
@ -362,10 +362,10 @@ is at work, it will have the value of ``autoup'', otherwise it
|
||||
will be ``noautoup''.
|
||||
.TP
|
||||
.I aliases
|
||||
The console aliases are presented in a comma separated list.
|
||||
The console aliases are presented in a comma-separated list.
|
||||
.TP
|
||||
.I options
|
||||
The active options for the console are presented in a comma separated list.
|
||||
The active options for the console are presented in a comma-separated list.
|
||||
.TP
|
||||
.I initcmd
|
||||
The initcmd configuration option for the console.
|
||||
@ -387,6 +387,12 @@ Commands are:
|
||||
.sp
|
||||
.PD 0
|
||||
.TP 13
|
||||
.B \.
|
||||
disconnect
|
||||
.TP
|
||||
.B ;
|
||||
move to another console
|
||||
.TP
|
||||
.B a
|
||||
attach read-write if nobody already is
|
||||
.TP
|
||||
@ -454,6 +460,9 @@ examine this group's devices and modes
|
||||
.B z
|
||||
suspend this connection
|
||||
.TP
|
||||
.B |
|
||||
attach a local command to the console
|
||||
.TP
|
||||
.B ?
|
||||
display list of commands
|
||||
.TP
|
||||
@ -467,8 +476,6 @@ replay the last line only
|
||||
send character having octal code
|
||||
.IR ooo " (must"
|
||||
specify three octal digits)
|
||||
.IP \.
|
||||
disconnect
|
||||
.PD
|
||||
.PP
|
||||
If any other character is hit after the escape sequence, all three characters
|
||||
|
@ -88,15 +88,6 @@
|
||||
#define const
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef __NetBSD__
|
||||
#if 1
|
||||
static const char rcsid[] = "Id: chat.c,v 1.26 1999/12/23 01:39:54 paulus Exp ";
|
||||
#else
|
||||
__RCSID("$NetBSD: chat.c,v 1.25 2001/09/24 13:22:38 wiz Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
|
||||
%define pkg conserver
|
||||
%define ver 8.0.7
|
||||
%define ver 8.1.3
|
||||
|
||||
# define the name of the machine on which the main conserver
|
||||
# daemon will be running if you don't want to use the default
|
||||
|
@ -1,7 +1,7 @@
|
||||
PKG="conserver"
|
||||
NAME="Console server and client"
|
||||
CATEGORY="system"
|
||||
VERSION="8.0.7"
|
||||
VERSION="8.1.3"
|
||||
DESC="Console server and client"
|
||||
CLASSES=none
|
||||
ARCH=sparc
|
||||
|
@ -1,17 +1,18 @@
|
||||
[Enter `^Ec?' for help]
|
||||
[help]
|
||||
. disconnect a attach read/write
|
||||
b send broadcast message c toggle flow control
|
||||
d down a console e change escape sequence
|
||||
f force attach read/write g group info
|
||||
i information dump L toggle logging on/off
|
||||
l? break sequence list l0 send break per config file
|
||||
l1-9 send specific break sequence m display the message of the day
|
||||
o (re)open the tty and log file p replay the last 60 lines
|
||||
r replay the last 20 lines s spy read only
|
||||
u show host status v show version info
|
||||
w who is on this console x show console baud info
|
||||
z suspend the connection <cr> ignore/abort command
|
||||
? print this message ^R replay the last line
|
||||
. disconnect ; move to another console
|
||||
a attach read/write b send broadcast message
|
||||
c toggle flow control d down a console
|
||||
e change escape sequence f force attach read/write
|
||||
g group info i information dump
|
||||
L toggle logging on/off l? break sequence list
|
||||
l0 send break per config file l1-9 send specific break sequence
|
||||
m display the message of the day o (re)open the tty and log file
|
||||
p replay the last 60 lines r replay the last 20 lines
|
||||
s spy read only u show host status
|
||||
v show version info w who is on this console
|
||||
x show console baud info z suspend the connection
|
||||
| attach local command ? print this message
|
||||
<cr> ignore/abort command ^R replay the last line
|
||||
\ooo send character by octal code
|
||||
[disconnect]
|
||||
|
@ -1,17 +1,18 @@
|
||||
[Enter `^Ec?' for help]
|
||||
[help]
|
||||
. disconnect a attach read/write
|
||||
b send broadcast message c toggle flow control
|
||||
d down a console e change escape sequence
|
||||
f force attach read/write g group info
|
||||
i information dump L toggle logging on/off
|
||||
l? break sequence list l0 send break per config file
|
||||
l1-9 send specific break sequence m display the message of the day
|
||||
o (re)open the tty and log file p replay the last 60 lines
|
||||
r replay the last 20 lines s spy read only
|
||||
u show host status v show version info
|
||||
w who is on this console x show console baud info
|
||||
z suspend the connection <cr> ignore/abort command
|
||||
? print this message ^R replay the last line
|
||||
. disconnect ; move to another console
|
||||
a attach read/write b send broadcast message
|
||||
c toggle flow control d down a console
|
||||
e change escape sequence f force attach read/write
|
||||
g group info i information dump
|
||||
L toggle logging on/off l? break sequence list
|
||||
l0 send break per config file l1-9 send specific break sequence
|
||||
m display the message of the day o (re)open the tty and log file
|
||||
p replay the last 60 lines r replay the last 20 lines
|
||||
s spy read only u show host status
|
||||
v show version info w who is on this console
|
||||
x show console baud info z suspend the connection
|
||||
| attach local command ? print this message
|
||||
<cr> ignore/abort command ^R replay the last line
|
||||
\ooo send character by octal code
|
||||
[disconnect]
|
||||
|
Reference in New Issue
Block a user