mirror of
https://github.com/bstansell/conserver.git
synced 2024-12-19 21:07:54 +00:00
Imported from conserver-8.1.6.tar.gz
This commit is contained in:
parent
5c430d220b
commit
cf461c7ce8
18
CHANGES
18
CHANGES
@ -1,6 +1,22 @@
|
||||
CHANGES
|
||||
=======
|
||||
|
||||
version 8.1.6 (May 25, 2004):
|
||||
- added ability to configure client via sytem-wide console.cf
|
||||
file and per-user .consolerc - suggested by Erik Sjolund
|
||||
<erik.sjolund@sbc.su.se>
|
||||
- fixed bug where break strings were not properly sent -
|
||||
reported by Tim Small <tim@buttersideup.com>
|
||||
- fixed bug in config file 'protocol' value handling - reported
|
||||
by Kees Cook <kees@osdl.org>
|
||||
- conserver no longer uses the local domain name in the default
|
||||
access list (the default list is only created if no access
|
||||
list is specified in the configuration file) - inspired by
|
||||
William P LePera <lepera@us.ibm.com>
|
||||
- added a 'terminal' console configuration block for printing
|
||||
strings when attaching and detaching from consoles - suggested
|
||||
by Richard Threadgill <richardt@tellme.com>
|
||||
|
||||
version 8.1.5 (May 7, 2004):
|
||||
- changed remaining O_NDELAY flags to O_NONBLOCK
|
||||
- added PROTOCOLS file to describe the client/server protocol
|
||||
@ -722,5 +738,5 @@ before version 6.05:
|
||||
and enhancements of various types were applied.
|
||||
|
||||
#
|
||||
# $Id: CHANGES,v 1.174 2004/05/07 16:04:58 bryan Exp $
|
||||
# $Id: CHANGES,v 1.179 2004/05/26 00:14:07 bryan Exp $
|
||||
#
|
||||
|
14
TODO
14
TODO
@ -86,26 +86,14 @@ Bryan Stansell
|
||||
- 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
|
||||
|
||||
- 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.47 2004/03/12 17:34:49 bryan Exp $
|
||||
# $Id: TODO,v 1.49 2004/05/25 00:38:11 bryan Exp $
|
||||
#
|
||||
|
@ -1,5 +1,8 @@
|
||||
/* config.h.in. Generated from configure.in by autoheader. */
|
||||
|
||||
/* Client config file path */
|
||||
#undef CLIENTCONFIGFILE
|
||||
|
||||
/* Config file path */
|
||||
#undef CONFIGFILE
|
||||
|
||||
|
69
configure
vendored
69
configure
vendored
@ -847,6 +847,8 @@ Optional Packages:
|
||||
--with-port=PORT Specify port number [conserver]
|
||||
--with-base=PORT Base port for secondary channel [0]
|
||||
--with-master=MASTER Specify master server hostname [console]
|
||||
--with-ccffile=CFFILE Specify client config filename
|
||||
[SYSCONFDIR/console.cf]
|
||||
--with-cffile=CFFILE Specify config filename
|
||||
[SYSCONFDIR/conserver.cf]
|
||||
--with-pwdfile=PWDFILE Specify password filename
|
||||
@ -1432,6 +1434,47 @@ _ACEOF
|
||||
echo "${ECHO_T}'console'" >&6
|
||||
fi;
|
||||
|
||||
echo "$as_me:$LINENO: checking for client configuration filename" >&5
|
||||
echo $ECHO_N "checking for client configuration filename... $ECHO_C" >&6
|
||||
|
||||
# Check whether --with-ccffile or --without-ccffile was given.
|
||||
if test "${with_ccffile+set}" = set; then
|
||||
withval="$with_ccffile"
|
||||
case "$withval" in
|
||||
yes|no)
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define CLIENTCONFIGFILE SYSCONFDIR "/console.cf"
|
||||
_ACEOF
|
||||
|
||||
echo "$as_me:$LINENO: result: '$sysconfdir/console.cf'" >&5
|
||||
echo "${ECHO_T}'$sysconfdir/console.cf'" >&6
|
||||
;;
|
||||
[\\/]* | ?:[\\/]* )
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define CLIENTCONFIGFILE "$withval"
|
||||
_ACEOF
|
||||
|
||||
echo "$as_me:$LINENO: result: '$withval'" >&5
|
||||
echo "${ECHO_T}'$withval'" >&6
|
||||
;;
|
||||
*)
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define CLIENTCONFIGFILE SYSCONFDIR "/$withval"
|
||||
_ACEOF
|
||||
|
||||
echo "$as_me:$LINENO: result: '$sysconfdir/$withval'" >&5
|
||||
echo "${ECHO_T}'$sysconfdir/$withval'" >&6
|
||||
;;
|
||||
esac
|
||||
else
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define CLIENTCONFIGFILE SYSCONFDIR "/console.cf"
|
||||
_ACEOF
|
||||
|
||||
echo "$as_me:$LINENO: result: '$sysconfdir/console.cf'" >&5
|
||||
echo "${ECHO_T}'$sysconfdir/console.cf'" >&6
|
||||
fi;
|
||||
|
||||
echo "$as_me:$LINENO: checking for configuration filename" >&5
|
||||
echo $ECHO_N "checking for configuration filename... $ECHO_C" >&6
|
||||
|
||||
@ -1698,6 +1741,7 @@ fi;
|
||||
|
||||
echo "$as_me:$LINENO: checking whether to use Unix domain sockets" >&5
|
||||
echo $ECHO_N "checking whether to use Unix domain sockets... $ECHO_C" >&6
|
||||
cons_with_uds="NO"
|
||||
|
||||
# Check whether --with-uds or --without-uds was given.
|
||||
if test "${with_uds+set}" = set; then
|
||||
@ -1714,6 +1758,7 @@ _ACEOF
|
||||
|
||||
echo "$as_me:$LINENO: result: /tmp/conserver" >&5
|
||||
echo "${ECHO_T}/tmp/conserver" >&6
|
||||
cons_with_uds="YES"
|
||||
;;
|
||||
no)
|
||||
echo "$as_me:$LINENO: result: no" >&5
|
||||
@ -1730,6 +1775,7 @@ _ACEOF
|
||||
|
||||
echo "$as_me:$LINENO: result: '$withval'" >&5
|
||||
echo "${ECHO_T}'$withval'" >&6
|
||||
cons_with_uds="YES"
|
||||
if expr "$withval" : '/' >/dev/null 2>&1; then
|
||||
:
|
||||
else
|
||||
@ -5424,6 +5470,7 @@ fi
|
||||
|
||||
|
||||
|
||||
cons_with_libwrap="NO"
|
||||
|
||||
# Check whether --with-libwrap or --without-libwrap was given.
|
||||
if test "${with_libwrap+set}" = set; then
|
||||
@ -5627,6 +5674,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||
(exit $ac_status); }; }; then
|
||||
echo "$as_me:$LINENO: result: yes" >&5
|
||||
echo "${ECHO_T}yes" >&6
|
||||
cons_with_libwrap="YES"
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define USE_LIBWRAP 1
|
||||
_ACEOF
|
||||
@ -5685,6 +5733,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||
(exit $ac_status); }; }; then
|
||||
echo "$as_me:$LINENO: result: yes" >&5
|
||||
echo "${ECHO_T}yes" >&6
|
||||
cons_with_libwrap="YES"
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define USE_LIBWRAP 1
|
||||
_ACEOF
|
||||
@ -5714,6 +5763,7 @@ fi
|
||||
|
||||
fi;
|
||||
|
||||
cons_with_openssl="NO"
|
||||
|
||||
# Check whether --with-openssl or --without-openssl was given.
|
||||
if test "${with_openssl+set}" = set; then
|
||||
@ -5916,6 +5966,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||
(exit $ac_status); }; }; then
|
||||
echo "$as_me:$LINENO: result: yes" >&5
|
||||
echo "${ECHO_T}yes" >&6
|
||||
cons_with_openssl="YES"
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_OPENSSL 1
|
||||
_ACEOF
|
||||
@ -5943,6 +5994,7 @@ fi
|
||||
|
||||
fi;
|
||||
|
||||
cons_with_dmalloc="NO"
|
||||
|
||||
# Check whether --with-dmalloc or --without-dmalloc was given.
|
||||
if test "${with_dmalloc+set}" = set; then
|
||||
@ -6145,6 +6197,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||
(exit $ac_status); }; }; then
|
||||
echo "$as_me:$LINENO: result: yes" >&5
|
||||
echo "${ECHO_T}yes" >&6
|
||||
cons_with_dmalloc="YES"
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_DMALLOC 1
|
||||
_ACEOF
|
||||
@ -6175,6 +6228,7 @@ fi;
|
||||
|
||||
|
||||
|
||||
cons_with_pam="NO"
|
||||
echo "$as_me:$LINENO: checking for PAM support" >&5
|
||||
echo $ECHO_N "checking for PAM support... $ECHO_C" >&6
|
||||
|
||||
@ -6371,6 +6425,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||
(exit $ac_status); }; }; then
|
||||
echo "$as_me:$LINENO: result: yes" >&5
|
||||
echo "${ECHO_T}yes" >&6
|
||||
cons_with_pam="YES"
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_PAM 1
|
||||
_ACEOF
|
||||
@ -6431,6 +6486,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||
(exit $ac_status); }; }; then
|
||||
echo "$as_me:$LINENO: result: yes" >&5
|
||||
echo "${ECHO_T}yes" >&6
|
||||
cons_with_pam="YES"
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_PAM 1
|
||||
_ACEOF
|
||||
@ -8665,3 +8721,16 @@ if test "$no_create" != yes; then
|
||||
$ac_cs_success || { (exit 1); exit 1; }
|
||||
fi
|
||||
|
||||
|
||||
|
||||
echo "=============================================================="
|
||||
echo " Feature Summary"
|
||||
echo ""
|
||||
echo " Unix domain sockets (--with-uds) : $cons_with_uds"
|
||||
echo " TCP wrappers (--with-libwrap): $cons_with_libwrap"
|
||||
echo " OpenSSL (--with-openssl): $cons_with_openssl"
|
||||
echo " dmalloc (--with-dmalloc): $cons_with_dmalloc"
|
||||
echo " PAM support (--with-pam) : $cons_with_pam"
|
||||
echo ""
|
||||
echo "=============================================================="
|
||||
|
||||
|
47
configure.in
47
configure.in
@ -4,6 +4,7 @@ AH_TEMPLATE([DEFPORT], [Socket used to communicate])
|
||||
AH_TEMPLATE([DEFBASEPORT], [Base socket used for secondary channel])
|
||||
AH_TEMPLATE([MASTERHOST], [Hostname of console server])
|
||||
AH_TEMPLATE([CONFIGFILE], [Config file path])
|
||||
AH_TEMPLATE([CLIENTCONFIGFILE], [Client config file path])
|
||||
AH_TEMPLATE([PASSWDFILE], [Password file path])
|
||||
AH_TEMPLATE([LOGFILEPATH], [Logfile path])
|
||||
AH_TEMPLATE([MAXMEMB], [Number of consoles per child process])
|
||||
@ -98,6 +99,26 @@ AC_ARG_WITH(master,
|
||||
[AC_DEFINE_UNQUOTED(MASTERHOST, "console")
|
||||
AC_MSG_RESULT('console')])
|
||||
|
||||
AC_MSG_CHECKING(for client configuration filename)
|
||||
AC_ARG_WITH(ccffile,
|
||||
AS_HELP_STRING([--with-ccffile=CFFILE],[Specify client config filename @<:@SYSCONFDIR/console.cf@:>@]),
|
||||
[case "$withval" in
|
||||
yes|no)
|
||||
AC_DEFINE_UNQUOTED(CLIENTCONFIGFILE, [SYSCONFDIR "/console.cf"])
|
||||
AC_MSG_RESULT('$sysconfdir/console.cf')
|
||||
;;
|
||||
[[\\/]]* | ?:[[\\/]]* )
|
||||
AC_DEFINE_UNQUOTED(CLIENTCONFIGFILE, ["$withval"])
|
||||
AC_MSG_RESULT('$withval')
|
||||
;;
|
||||
*)
|
||||
AC_DEFINE_UNQUOTED(CLIENTCONFIGFILE, [SYSCONFDIR "/$withval"])
|
||||
AC_MSG_RESULT('$sysconfdir/$withval')
|
||||
;;
|
||||
esac],
|
||||
[AC_DEFINE_UNQUOTED(CLIENTCONFIGFILE, [SYSCONFDIR "/console.cf"])
|
||||
AC_MSG_RESULT('$sysconfdir/console.cf')])
|
||||
|
||||
AC_MSG_CHECKING(for configuration filename)
|
||||
AC_ARG_WITH(cffile,
|
||||
AS_HELP_STRING([--with-cffile=CFFILE],[Specify config filename @<:@SYSCONFDIR/conserver.cf@:>@]),
|
||||
@ -233,6 +254,7 @@ AC_ARG_WITH(extmsgs,
|
||||
esac],[AC_MSG_RESULT(no)])
|
||||
|
||||
AC_MSG_CHECKING(whether to use Unix domain sockets)
|
||||
cons_with_uds="NO"
|
||||
AC_ARG_WITH(uds,
|
||||
AS_HELP_STRING([--with-uds@<:@=DIR@:>@ ],
|
||||
[Use Unix domain sockets for client/server communication @<:@/tmp/conserver@:>@]),
|
||||
@ -241,6 +263,7 @@ AC_ARG_WITH(uds,
|
||||
AC_DEFINE_UNQUOTED(UDSDIR, "/tmp/conserver")
|
||||
AC_DEFINE(USE_UNIX_DOMAIN_SOCKETS)
|
||||
AC_MSG_RESULT([/tmp/conserver])
|
||||
cons_with_uds="YES"
|
||||
;;
|
||||
no)
|
||||
AC_MSG_RESULT(no)
|
||||
@ -249,6 +272,7 @@ AC_ARG_WITH(uds,
|
||||
AC_DEFINE_UNQUOTED(UDSDIR, "$withval")
|
||||
AC_DEFINE(USE_UNIX_DOMAIN_SOCKETS)
|
||||
AC_MSG_RESULT('$withval')
|
||||
cons_with_uds="YES"
|
||||
if expr "$withval" : '/' >/dev/null 2>&1; then
|
||||
:
|
||||
else
|
||||
@ -343,6 +367,7 @@ AC_SEARCH_LIBS(crypt,crypt)
|
||||
AC_SUBST(CONSLIBS)
|
||||
AC_SUBST(CONSCPPFLAGS)
|
||||
AC_SUBST(CONSLDFLAGS)
|
||||
cons_with_libwrap="NO"
|
||||
AC_ARG_WITH(libwrap,
|
||||
AS_HELP_STRING([--with-libwrap@<:@=PATH@:>@],
|
||||
[Compile in libwrap (tcp_wrappers) support]),
|
||||
@ -370,6 +395,7 @@ AC_ARG_WITH(libwrap,
|
||||
int deny_severity = 0;
|
||||
],[hosts_access((void *)0)],
|
||||
[AC_MSG_RESULT(yes)
|
||||
cons_with_libwrap="YES"
|
||||
AC_DEFINE(USE_LIBWRAP)
|
||||
CONSLIBS="$CONSLIBS -lwrap"
|
||||
CONSLDFLAGS="$CONSLDFLAGS $WRAPLDFLAGS"
|
||||
@ -382,6 +408,7 @@ AC_ARG_WITH(libwrap,
|
||||
int deny_severity = 0;
|
||||
],[hosts_access((void *)0)],
|
||||
[AC_MSG_RESULT(yes)
|
||||
cons_with_libwrap="YES"
|
||||
AC_DEFINE(USE_LIBWRAP)
|
||||
CONSLIBS="$CONSLIBS -lwrap -lnsl"
|
||||
CONSLDFLAGS="$CONSLDFLAGS $WRAPLDFLAGS"
|
||||
@ -393,6 +420,7 @@ AC_ARG_WITH(libwrap,
|
||||
fi]
|
||||
)
|
||||
|
||||
cons_with_openssl="NO"
|
||||
AC_ARG_WITH(openssl,
|
||||
AS_HELP_STRING([--with-openssl@<:@=PATH@:>@],
|
||||
[Compile in OpenSSL support]),
|
||||
@ -419,6 +447,7 @@ AC_ARG_WITH(openssl,
|
||||
AC_TRY_LINK([#include <openssl/ssl.h>
|
||||
],[SSL_library_init()],
|
||||
[AC_MSG_RESULT(yes)
|
||||
cons_with_openssl="YES"
|
||||
AC_DEFINE(HAVE_OPENSSL)
|
||||
have_openssl=yes],
|
||||
[AC_MSG_RESULT(no)])],)
|
||||
@ -431,6 +460,7 @@ AC_ARG_WITH(openssl,
|
||||
fi]
|
||||
)
|
||||
|
||||
cons_with_dmalloc="NO"
|
||||
AC_ARG_WITH(dmalloc,
|
||||
AS_HELP_STRING([--with-dmalloc@<:@=PATH@:>@],
|
||||
[Compile in dmalloc support]),
|
||||
@ -457,6 +487,7 @@ AC_ARG_WITH(dmalloc,
|
||||
AC_TRY_LINK([#include <dmalloc.h>
|
||||
],[dmalloc_debug(0)],
|
||||
[AC_MSG_RESULT(yes)
|
||||
cons_with_dmalloc="YES"
|
||||
AC_DEFINE(HAVE_DMALLOC)
|
||||
have_dmalloc=yes],
|
||||
[AC_MSG_RESULT(no)])],)
|
||||
@ -505,6 +536,7 @@ dnl else
|
||||
dnl AC_MSG_RESULT(no)
|
||||
dnl fi],[AC_MSG_RESULT(no)])
|
||||
|
||||
cons_with_pam="NO"
|
||||
AC_MSG_CHECKING(for PAM support)
|
||||
AC_ARG_WITH(pam,
|
||||
AS_HELP_STRING([--with-pam],
|
||||
@ -517,6 +549,7 @@ AC_ARG_WITH(pam,
|
||||
AC_MSG_CHECKING(for PAM library -lpam)
|
||||
AC_TRY_LINK_FUNC([pam_start],
|
||||
[AC_MSG_RESULT(yes)
|
||||
cons_with_pam="YES"
|
||||
AC_DEFINE(HAVE_PAM)
|
||||
CONSLIBS="$CONSLIBS -lpam"],
|
||||
[LIBS="$LIBS -ldl"
|
||||
@ -524,6 +557,7 @@ AC_ARG_WITH(pam,
|
||||
AC_MSG_CHECKING(for PAM library -lpam with -ldl)
|
||||
AC_TRY_LINK_FUNC([pam_end],
|
||||
[AC_MSG_RESULT(yes)
|
||||
cons_with_pam="YES"
|
||||
AC_DEFINE(HAVE_PAM)
|
||||
CONSLIBS="$CONSLIBS -lpam -ldl"],
|
||||
[AC_MSG_RESULT(no)])])],)
|
||||
@ -566,3 +600,16 @@ dnl ### Create output files. #######################################
|
||||
AC_CONFIG_FILES([Makefile conserver/Makefile conserver.cf/Makefile console/Makefile autologin/Makefile contrib/chat/Makefile])
|
||||
AC_CONFIG_FILES([conserver/conserver.rc], [chmod +x conserver/conserver.rc])
|
||||
AC_OUTPUT
|
||||
|
||||
[
|
||||
echo "=============================================================="
|
||||
echo " Feature Summary"
|
||||
echo ""
|
||||
echo " Unix domain sockets (--with-uds) : $cons_with_uds"
|
||||
echo " TCP wrappers (--with-libwrap): $cons_with_libwrap"
|
||||
echo " OpenSSL (--with-openssl): $cons_with_openssl"
|
||||
echo " dmalloc (--with-dmalloc): $cons_with_dmalloc"
|
||||
echo " PAM support (--with-pam) : $cons_with_pam"
|
||||
echo ""
|
||||
echo "=============================================================="
|
||||
]
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" $Id: conserver.cf.man,v 1.63 2004/05/07 03:42:51 bryan Exp $
|
||||
.TH CONSERVER.CF 5 "2004/05/07" "conserver-8.1.5" "conserver"
|
||||
.TH CONSERVER.CF 5 "2004/05/07" "conserver-8.1.6" "conserver"
|
||||
.SH NAME
|
||||
conserver.cf \- console configuration file for
|
||||
.BR conserver (8)
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" $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.5" "conserver"
|
||||
.TH CONSERVER.PASSWD 5 "2004/01/08" "conserver-8.1.6" "conserver"
|
||||
.SH NAME
|
||||
conserver.passwd \- user access information for
|
||||
.BR conserver (8)
|
||||
|
@ -181,11 +181,11 @@
|
||||
|
||||
<H3>Downloading</H3>
|
||||
|
||||
<P>The current version, released on May 7, 2004, is <A
|
||||
href="8.1.5.tar.gz">8.1.5.tar.gz</A>. You can get it via
|
||||
<P>The current version, released on May 25, 2004, is <A
|
||||
href="8.1.6.tar.gz">8.1.6.tar.gz</A>. You can get it via
|
||||
<A href=
|
||||
"ftp://ftp.conserver.com/conserver/8.1.5.tar.gz">FTP</A>
|
||||
or <A href="8.1.5.tar.gz">HTTP</A>. See the <A href=
|
||||
"ftp://ftp.conserver.com/conserver/8.1.6.tar.gz">FTP</A>
|
||||
or <A href="8.1.6.tar.gz">HTTP</A>. See the <A href=
|
||||
"CHANGES">CHANGES</A> file for information on the latest
|
||||
updates.</P>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: access.c,v 5.71 2003/11/20 13:56:38 bryan Exp $
|
||||
* $Id: access.c,v 5.73 2004/05/23 16:44:25 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -171,7 +171,8 @@ AccType(addr, peername)
|
||||
hname = he->h_aliases[a++]) {
|
||||
if ((revNames[a] = StrDup(hname)) == (char *)0)
|
||||
break;
|
||||
CONDDEBUG((1,"AccType(): revNames[%d]='%s'", a, hname));
|
||||
CONDDEBUG((1, "AccType(): revNames[%d]='%s'", a,
|
||||
hname));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -280,11 +281,26 @@ SetDefAccess(pAddr, pHost)
|
||||
char *pHost;
|
||||
#endif
|
||||
{
|
||||
char *pcDomain;
|
||||
char *addr;
|
||||
ACCESS *a;
|
||||
|
||||
while (pACList != (ACCESS *)0) {
|
||||
a = pACList->pACnext;
|
||||
DestroyAccessList(pACList);
|
||||
pACList = a;
|
||||
}
|
||||
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
if ((pACList = (ACCESS *)calloc(1, sizeof(ACCESS))) == (ACCESS *)0)
|
||||
OutOfMem();
|
||||
if ((pACList->pcwho = StrDup("127.0.0.1")) == (char *)0)
|
||||
OutOfMem();
|
||||
pACList->ctrust = 'a';
|
||||
CONDDEBUG((1, "SetDefAccess(): trust=%c, who=%s", pACList->ctrust,
|
||||
pACList->pcwho));
|
||||
#else
|
||||
while (pAddr->s_addr != (in_addr_t) 0) {
|
||||
char *addr;
|
||||
|
||||
addr = inet_ntoa(*pAddr);
|
||||
if ((a = (ACCESS *)calloc(1, sizeof(ACCESS))) == (ACCESS *)0)
|
||||
OutOfMem();
|
||||
@ -298,21 +314,7 @@ SetDefAccess(pAddr, pHost)
|
||||
pACList->pcwho));
|
||||
pAddr++;
|
||||
}
|
||||
|
||||
if ((char *)0 == (pcDomain = strchr(pHost, '.')))
|
||||
return;
|
||||
++pcDomain;
|
||||
|
||||
if ((a = (ACCESS *)calloc(1, sizeof(ACCESS))) == (ACCESS *)0)
|
||||
OutOfMem();
|
||||
if ((a->pcwho = StrDup(pcDomain)) == (char *)0)
|
||||
OutOfMem();
|
||||
a->ctrust = 'a';
|
||||
a->pACnext = pACList;
|
||||
pACList = a;
|
||||
|
||||
CONDDEBUG((1, "SetDefAccess(): trust=%c, who=%s", pACList->ctrust,
|
||||
pACList->pcwho));
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: consent.h,v 5.56 2004/02/20 14:58:14 bryan Exp $
|
||||
* $Id: consent.h,v 5.57 2004/05/21 04:38:02 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -96,7 +96,7 @@ typedef struct consent { /* console information */
|
||||
unsigned short port; /* port number | portinc * port */
|
||||
unsigned short portbase; /* port base */
|
||||
unsigned short portinc; /* port increment */
|
||||
unsigned short raw; /* raw or telnet protocol? */
|
||||
FLAG raw; /* raw or telnet protocol? */
|
||||
/* type == EXEC */
|
||||
char *exec; /* exec command */
|
||||
char *execsubst; /* exec substitution pattern */
|
||||
|
@ -1,6 +1,6 @@
|
||||
.\" @(#)conserver.8 01/06/91 OSU CIS; Thomas A. Fine
|
||||
.\" $Id: conserver.man,v 1.46 2004/04/13 18:19:26 bryan Exp $
|
||||
.TH CONSERVER 8 "2004/04/13" "conserver-8.1.5" "conserver"
|
||||
.\" $Id: conserver.man,v 1.47 2004/05/21 04:15:17 bryan Exp $
|
||||
.TH CONSERVER 8 "2004/05/21" "conserver-8.1.6" "conserver"
|
||||
.SH NAME
|
||||
conserver \- console server daemon
|
||||
.SH SYNOPSIS
|
||||
@ -297,8 +297,9 @@ However, if
|
||||
was used to enable Unix domain sockets for client/server communication,
|
||||
this points conserver to the directory where it should store the sockets.
|
||||
The default
|
||||
.IR master
|
||||
directory, ``/tmp/conserver'',
|
||||
.I master
|
||||
directory
|
||||
.RB (`` /tmp/conserver '')
|
||||
may be changed at compile time using the
|
||||
.B --with-uds
|
||||
option.
|
||||
@ -454,7 +455,7 @@ The following default file locations may be overridden
|
||||
at compile time or by the command-line options described above.
|
||||
Run
|
||||
.B conserver \-V
|
||||
(with no other options) to see the defaults set at compile time.
|
||||
to see the defaults set at compile time.
|
||||
.PP
|
||||
.PD 0
|
||||
.TP 25
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: convert.c,v 1.8 2003/11/20 13:56:38 bryan Exp $
|
||||
* $Id: convert.c,v 1.9 2004/05/21 04:15:17 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -42,6 +42,10 @@
|
||||
#include <main.h>
|
||||
|
||||
|
||||
SECTION sections[] = {
|
||||
{(char *)0, (void *)0, (void *)0, (void *)0, (void *)0}
|
||||
};
|
||||
|
||||
void
|
||||
DestroyDataStructures()
|
||||
{
|
||||
@ -139,7 +143,7 @@ ReadLine2(fp, save, iLine)
|
||||
if (!peek && (ret == (char *)0)) {
|
||||
(*iLine)++;
|
||||
wholeline = BuildString(bufstr->string, wholestr);
|
||||
if (wholeline[0] == '\000')
|
||||
if (wholeline != (char *)0 && wholeline[0] == '\000')
|
||||
wholeline = (char *)0;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: cutil.c,v 1.116 2004/03/19 05:23:21 bryan Exp $
|
||||
* $Id: cutil.c,v 1.118 2004/05/25 00:38:15 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -10,6 +10,10 @@
|
||||
|
||||
#include <cutil.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#if HAVE_SYS_SOCKIO_H
|
||||
# include <sys/sockio.h>
|
||||
#endif
|
||||
#if HAVE_OPENSSL
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
@ -29,6 +33,7 @@ fd_set winit;
|
||||
int maxfd = 0;
|
||||
int debugLineNo = 0;
|
||||
char *debugFileName = (char *)0;
|
||||
int isMaster = 1;
|
||||
|
||||
/* in the routines below (the init code) we can bomb if malloc fails (ksb)
|
||||
*/
|
||||
@ -2122,6 +2127,189 @@ PruneSpace(string)
|
||||
return string;
|
||||
}
|
||||
|
||||
/* fills the myAddrs array with host interface addresses */
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ProbeInterfaces(in_addr_t bindAddr)
|
||||
#else
|
||||
ProbeInterfaces(bindAddr)
|
||||
in_addr_t bindAddr;
|
||||
#endif
|
||||
{
|
||||
#ifdef SIOCGIFCONF
|
||||
struct ifconf ifc;
|
||||
struct ifreq *ifr;
|
||||
#ifdef SIOCGIFFLAGS
|
||||
struct ifreq ifrcopy;
|
||||
#endif
|
||||
int sock;
|
||||
int r = 0, m = 0;
|
||||
int bufsize = 2048;
|
||||
int count = 0;
|
||||
|
||||
/* if we use -M, just fill the array with that interface */
|
||||
if (bindAddr != INADDR_ANY) {
|
||||
myAddrs = (struct in_addr *)calloc(2, sizeof(struct in_addr));
|
||||
if (myAddrs == (struct in_addr *)0)
|
||||
OutOfMem();
|
||||
#if HAVE_MEMCPY
|
||||
memcpy(&(myAddrs[0].s_addr), &bindAddr, sizeof(in_addr_t));
|
||||
#else
|
||||
bcopy(&bindAddr, &(myAddrs[0].s_addr), sizeof(in_addr_t));
|
||||
#endif
|
||||
Verbose("interface address %s (-M option)", inet_ntoa(myAddrs[0]));
|
||||
return;
|
||||
}
|
||||
|
||||
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
|
||||
Error("ProbeInterfaces(): socket(): %s", strerror(errno));
|
||||
Bye(EX_OSERR);
|
||||
}
|
||||
|
||||
while (bufsize) {
|
||||
ifc.ifc_len = bufsize;
|
||||
ifc.ifc_req = (struct ifreq *)malloc(ifc.ifc_len);
|
||||
if (ifc.ifc_req == (struct ifreq *)0)
|
||||
OutOfMem();
|
||||
if (ioctl(sock, SIOCGIFCONF, &ifc) != 0) {
|
||||
free(ifc.ifc_req);
|
||||
close(sock);
|
||||
Error("ProbeInterfaces(): ioctl(SIOCGIFCONF): %s",
|
||||
strerror(errno));
|
||||
Bye(EX_OSERR);
|
||||
}
|
||||
/* if the return size plus a 512 byte "buffer zone" is less than
|
||||
* the buffer we passed in (bufsize), we're done. otherwise
|
||||
* allocate a bigger buffer and try again. with a too-small
|
||||
* buffer, some implementations (freebsd) will fill the buffer
|
||||
* best it can (leaving a gap - returning <=bufsize) and others
|
||||
* (linux) will return a buffer length the same size as passed
|
||||
* in (==bufsize). so, we'll assume a 512 byte gap would have
|
||||
* been big enough to put one more record and as long as we have
|
||||
* that "buffer zone", we should have all the interfaces.
|
||||
*/
|
||||
if (ifc.ifc_len + 512 < bufsize)
|
||||
break;
|
||||
free(ifc.ifc_req);
|
||||
bufsize += 2048;
|
||||
}
|
||||
|
||||
/* this is probably way overkill, but better to kill a few bytes
|
||||
* than loop through looking for valid interfaces that are up
|
||||
* twice, huh?
|
||||
*/
|
||||
count = ifc.ifc_len / sizeof(*ifr);
|
||||
CONDDEBUG((1, "ProbeInterfaces(): ifc_len==%d max_count==%d",
|
||||
ifc.ifc_len, count));
|
||||
|
||||
/* set up myAddrs array */
|
||||
if (myAddrs != (struct in_addr *)0)
|
||||
free(myAddrs);
|
||||
myAddrs = (struct in_addr *)0;
|
||||
if (count == 0) {
|
||||
free(ifc.ifc_req);
|
||||
close(sock);
|
||||
return;
|
||||
}
|
||||
myAddrs = (struct in_addr *)calloc(count + 1, sizeof(struct in_addr));
|
||||
if (myAddrs == (struct in_addr *)0)
|
||||
OutOfMem();
|
||||
|
||||
for (m = r = 0; r < ifc.ifc_len;) {
|
||||
struct sockaddr *sa;
|
||||
ifr = (struct ifreq *)&ifc.ifc_buf[r];
|
||||
sa = (struct sockaddr *)&ifr->ifr_addr;
|
||||
/* don't use less than a ifreq sized chunk */
|
||||
if ((ifc.ifc_len - r) < sizeof(*ifr))
|
||||
break;
|
||||
#ifdef HAVE_SA_LEN
|
||||
if (sa->sa_len > sizeof(ifr->ifr_addr))
|
||||
r += sizeof(ifr->ifr_name) + sa->sa_len;
|
||||
else
|
||||
#endif
|
||||
r += sizeof(*ifr);
|
||||
|
||||
if (sa->sa_family == AF_INET) {
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
||||
#ifdef SIOCGIFFLAGS
|
||||
/* make sure the interface is up */
|
||||
ifrcopy = *ifr;
|
||||
if ((ioctl(sock, SIOCGIFFLAGS, &ifrcopy) == 0) &&
|
||||
((ifrcopy.ifr_flags & IFF_UP) == 0))
|
||||
continue;
|
||||
#endif
|
||||
CONDDEBUG((1, "ProbeInterfaces(): name=%s addr=%s",
|
||||
ifr->ifr_name, inet_ntoa(sin->sin_addr)));
|
||||
#if HAVE_MEMCPY
|
||||
memcpy(&myAddrs[m], &(sin->sin_addr), sizeof(struct in_addr));
|
||||
#else
|
||||
bcopy(&(sin->sin_addr), &myAddrs[m], sizeof(struct in_addr));
|
||||
#endif
|
||||
Verbose("interface address %s (%s)", inet_ntoa(myAddrs[m]),
|
||||
ifr->ifr_name);
|
||||
m++;
|
||||
}
|
||||
}
|
||||
if (m == 0) {
|
||||
free(myAddrs);
|
||||
myAddrs = (struct in_addr *)0;
|
||||
}
|
||||
close(sock);
|
||||
free(ifc.ifc_req);
|
||||
#else /* use the hostname like the old code did (but use all addresses!) */
|
||||
int count;
|
||||
struct hostent *he;
|
||||
|
||||
/* if we use -M, just fill the array with that interface */
|
||||
if (bindAddr != INADDR_ANY) {
|
||||
myAddrs = (struct in_addr *)calloc(2, sizeof(struct in_addr));
|
||||
if (myAddrs == (struct in_addr *)0)
|
||||
OutOfMem();
|
||||
#if HAVE_MEMCPY
|
||||
memcpy(&(myAddrs[0].s_addr), &bindAddr, sizeof(in_addr_t));
|
||||
#else
|
||||
bcopy(&bindAddr, &(myAddrs[0].s_addr), sizeof(in_addr_t));
|
||||
#endif
|
||||
Verbose("interface address %s (-M option)", inet_ntoa(myAddrs[0]));
|
||||
return;
|
||||
}
|
||||
|
||||
Verbose("using hostname for interface addresses");
|
||||
if ((struct hostent *)0 == (he = gethostbyname(myHostname))) {
|
||||
Error("ProbeInterfaces(): gethostbyname(%s): %s", myHostname,
|
||||
hstrerror(h_errno));
|
||||
return;
|
||||
}
|
||||
if (4 != he->h_length || AF_INET != he->h_addrtype) {
|
||||
Error
|
||||
("ProbeInterfaces(): gethostbyname(%s): wrong address size (4 != %d) or address family (%d != %d)",
|
||||
myHostname, he->h_length, AF_INET, he->h_addrtype);
|
||||
return;
|
||||
}
|
||||
|
||||
for (count = 0; he->h_addr_list[count] != (char *)0; count++);
|
||||
if (myAddrs != (struct in_addr *)0)
|
||||
free(myAddrs);
|
||||
myAddrs = (struct in_addr *)0;
|
||||
if (count == 0)
|
||||
return;
|
||||
myAddrs = (struct in_addr *)calloc(count + 1, sizeof(struct in_addr));
|
||||
if (myAddrs == (struct in_addr *)0)
|
||||
OutOfMem();
|
||||
for (count--; count >= 0; count--) {
|
||||
#if HAVE_MEMCPY
|
||||
memcpy(&(myAddrs[count].s_addr), he->h_addr_list[count],
|
||||
he->h_length);
|
||||
#else
|
||||
bcopy(he->h_addr_list[count], &(myAddrs[count].s_addr),
|
||||
he->h_length);
|
||||
#endif
|
||||
Verbose("interface address %s (hostname address)",
|
||||
inet_ntoa(myAddrs[count]));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
#if PROTOTYPES
|
||||
IsMe(char *id)
|
||||
@ -2388,3 +2576,725 @@ ParseIACBuf(cfp, msg, len)
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
/* the format of the file should be as follows
|
||||
*
|
||||
* <section keyword> [section name] {
|
||||
* <item keyword> [item value];
|
||||
* .
|
||||
* .
|
||||
* }
|
||||
*
|
||||
* whitespace gets retained in [section name], and [item value]
|
||||
* values. for example,
|
||||
*
|
||||
* users bryan todd ;
|
||||
*
|
||||
* will give users the value of 'bryan todd'. the leading and
|
||||
* trailing whitespace is nuked, but the middle stuff isn't.
|
||||
*
|
||||
* a little note about the 'state' var...
|
||||
* START = before <section keyword>
|
||||
* NAME = before [section name]
|
||||
* LEFTB = before left curly brace
|
||||
* KEY = before <item keyword>
|
||||
* VALUE = before [item value]
|
||||
* SEMI = before semi-colon
|
||||
*/
|
||||
|
||||
typedef enum states {
|
||||
START,
|
||||
NAME,
|
||||
LEFTB,
|
||||
KEY,
|
||||
VALUE,
|
||||
SEMI
|
||||
} STATES;
|
||||
|
||||
typedef enum tokens {
|
||||
DONE,
|
||||
LEFTBRACE,
|
||||
RIGHTBRACE,
|
||||
SEMICOLON,
|
||||
WORD,
|
||||
INCLUDE
|
||||
} TOKEN;
|
||||
|
||||
int line = 1; /* current line number */
|
||||
char *file = (char *)0;
|
||||
|
||||
TOKEN
|
||||
#if PROTOTYPES
|
||||
GetWord(FILE *fp, int *line, short spaceok, STRING *word)
|
||||
#else
|
||||
GetWord(fp, line, spaceok, word)
|
||||
FILE *fp;
|
||||
int *line;
|
||||
short spaceok;
|
||||
STRING *word;
|
||||
#endif
|
||||
{
|
||||
int c;
|
||||
short backslash = 0;
|
||||
short quote = 0;
|
||||
short comment = 0;
|
||||
short sawQuote = 0;
|
||||
short quotedBackslash = 0;
|
||||
char *include = "include";
|
||||
short checkInc = -1;
|
||||
/* checkInc == -3, saw #include
|
||||
* == -2, saw nothin'
|
||||
* == -1, saw \n or start of file
|
||||
* == 0, saw "\n#"
|
||||
*/
|
||||
|
||||
BuildString((char *)0, word);
|
||||
while ((c = fgetc(fp)) != EOF) {
|
||||
if (c == '\n') {
|
||||
(*line)++;
|
||||
if (checkInc == -2)
|
||||
checkInc = -1;
|
||||
}
|
||||
if (comment) {
|
||||
if (c == '\n')
|
||||
comment = 0;
|
||||
if (checkInc >= 0) {
|
||||
if (include[checkInc] == '\000') {
|
||||
if (isspace(c))
|
||||
checkInc = -3;
|
||||
} else if (c == include[checkInc])
|
||||
checkInc++;
|
||||
else
|
||||
checkInc = -2;
|
||||
} else if (checkInc == -3) {
|
||||
static STRING *fname = (STRING *)0;
|
||||
if (fname == (STRING *)0)
|
||||
fname = AllocString();
|
||||
if (fname->used != 0 || !isspace(c)) {
|
||||
if (c == '\n') {
|
||||
if (fname->used > 0) {
|
||||
while (fname->used > 1 && isspace((int)
|
||||
(fname->
|
||||
string
|
||||
[fname->
|
||||
used -
|
||||
2])))
|
||||
fname->used--;
|
||||
if (fname->used > 0)
|
||||
fname->string[fname->used - 1] = '\000';
|
||||
}
|
||||
checkInc = -2;
|
||||
if (fname->used > 0) {
|
||||
BuildString((char *)0, word);
|
||||
BuildString(fname->string, word);
|
||||
BuildString((char *)0, fname);
|
||||
return INCLUDE;
|
||||
}
|
||||
} else
|
||||
BuildStringChar(c, fname);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (backslash) {
|
||||
BuildStringChar(c, word);
|
||||
backslash = 0;
|
||||
continue;
|
||||
}
|
||||
if (quote) {
|
||||
if (c == '"') {
|
||||
if (quotedBackslash) {
|
||||
BuildStringChar(c, word);
|
||||
quotedBackslash = 0;
|
||||
} else
|
||||
quote = 0;
|
||||
} else {
|
||||
if (quotedBackslash) {
|
||||
BuildStringChar('\\', word);
|
||||
quotedBackslash = 0;
|
||||
}
|
||||
if (c == '\\')
|
||||
quotedBackslash = 1;
|
||||
else
|
||||
BuildStringChar(c, word);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (c == '\\') {
|
||||
backslash = 1;
|
||||
} else if (c == '#') {
|
||||
comment = 1;
|
||||
if (checkInc == -1)
|
||||
checkInc = 0;
|
||||
} else if (c == '"') {
|
||||
quote = 1;
|
||||
sawQuote = 1;
|
||||
} else if (isspace(c)) {
|
||||
if (word->used <= 1)
|
||||
continue;
|
||||
if (spaceok) {
|
||||
BuildStringChar(c, word);
|
||||
continue;
|
||||
}
|
||||
gotword:
|
||||
while (word->used > 1 &&
|
||||
isspace((int)(word->string[word->used - 2])))
|
||||
word->used--;
|
||||
if (word->used > 0)
|
||||
word->string[word->used - 1] = '\000';
|
||||
return WORD;
|
||||
} else if (c == '{') {
|
||||
if (word->used <= 1 && !sawQuote) {
|
||||
BuildStringChar(c, word);
|
||||
return LEFTBRACE;
|
||||
} else {
|
||||
ungetc(c, fp);
|
||||
goto gotword;
|
||||
}
|
||||
} else if (c == '}') {
|
||||
if (word->used <= 1 && !sawQuote) {
|
||||
BuildStringChar(c, word);
|
||||
return RIGHTBRACE;
|
||||
} else {
|
||||
ungetc(c, fp);
|
||||
goto gotword;
|
||||
}
|
||||
} else if (c == ';') {
|
||||
if (word->used <= 1 && !sawQuote) {
|
||||
BuildStringChar(c, word);
|
||||
return SEMICOLON;
|
||||
} else {
|
||||
ungetc(c, fp);
|
||||
goto gotword;
|
||||
}
|
||||
} else {
|
||||
BuildStringChar(c, word);
|
||||
}
|
||||
}
|
||||
/* this should only happen in rare cases */
|
||||
if (quotedBackslash) {
|
||||
BuildStringChar('\\', word);
|
||||
quotedBackslash = 0;
|
||||
}
|
||||
/* if we saw "valid" data, it's a word */
|
||||
if (word->used > 1 || sawQuote)
|
||||
goto gotword;
|
||||
return DONE;
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ParseFile(char *filename, FILE *fp, int level)
|
||||
#else
|
||||
ParseFile(filename, fp, level)
|
||||
char *filename;
|
||||
FILE *fp;
|
||||
int level;
|
||||
#endif
|
||||
{
|
||||
/* things that should be used between recursions */
|
||||
static STATES state = START;
|
||||
static STRING *word = (STRING *)0;
|
||||
static short spaceok = 0;
|
||||
static int secIndex = 0;
|
||||
static int keyIndex = 0;
|
||||
|
||||
/* other stuff that's local to each recursion */
|
||||
char *p;
|
||||
TOKEN token = DONE;
|
||||
int nextline = 1; /* "next" line number */
|
||||
|
||||
if (level >= 10) {
|
||||
if (isMaster)
|
||||
Error("ParseFile(): nesting too deep, not parsing `%s'",
|
||||
filename);
|
||||
return;
|
||||
}
|
||||
|
||||
/* set some globals */
|
||||
line = 1;
|
||||
file = filename;
|
||||
|
||||
/* if we're parsing the base file, set static vars */
|
||||
if (level == 0) {
|
||||
state = START;
|
||||
spaceok = 0;
|
||||
secIndex = 0;
|
||||
keyIndex = 0;
|
||||
}
|
||||
|
||||
/* initialize local things */
|
||||
if (word == (STRING *)0)
|
||||
word = AllocString();
|
||||
|
||||
while ((token = GetWord(fp, &nextline, spaceok, word)) != DONE) {
|
||||
if (token == INCLUDE) {
|
||||
FILE *lfp;
|
||||
if ((FILE *)0 == (lfp = fopen(word->string, "r"))) {
|
||||
if (isMaster)
|
||||
Error("ParseFile(): fopen(%s): %s", word->string,
|
||||
strerror(errno));
|
||||
} else {
|
||||
char *fname;
|
||||
/* word gets destroyed, so save the name */
|
||||
fname = StrDup(word->string);
|
||||
ParseFile(fname, lfp, level + 1);
|
||||
fclose(lfp);
|
||||
free(fname);
|
||||
}
|
||||
} else {
|
||||
switch (state) {
|
||||
case START:
|
||||
switch (token) {
|
||||
case WORD:
|
||||
for (secIndex = 0;
|
||||
(p = sections[secIndex].id) != (char *)0;
|
||||
secIndex++) {
|
||||
if (strcasecmp(word->string, p) == 0) {
|
||||
CONDDEBUG((1,
|
||||
"ReadCfg(): got keyword '%s' [%s:%d]",
|
||||
word->string, file, line));
|
||||
state = NAME;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (state == START) {
|
||||
if (isMaster)
|
||||
Error("invalid keyword '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
}
|
||||
break;
|
||||
case LEFTBRACE:
|
||||
case RIGHTBRACE:
|
||||
case SEMICOLON:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case DONE: /* just shutting up gcc */
|
||||
case INCLUDE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NAME:
|
||||
switch (token) {
|
||||
case WORD:
|
||||
(*sections[secIndex].begin) (word->string);
|
||||
state = LEFTB;
|
||||
break;
|
||||
case RIGHTBRACE:
|
||||
if (isMaster)
|
||||
Error("premature token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
state = START;
|
||||
break;
|
||||
case LEFTBRACE:
|
||||
case SEMICOLON:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case DONE: /* just shutting up gcc */
|
||||
case INCLUDE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case LEFTB:
|
||||
switch (token) {
|
||||
case LEFTBRACE:
|
||||
state = KEY;
|
||||
break;
|
||||
case RIGHTBRACE:
|
||||
if (isMaster)
|
||||
Error("premature token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
(*sections[secIndex].abort) ();
|
||||
state = START;
|
||||
break;
|
||||
case SEMICOLON:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case WORD:
|
||||
if (isMaster)
|
||||
Error("invalid word '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case DONE: /* just shutting up gcc */
|
||||
case INCLUDE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case KEY:
|
||||
switch (token) {
|
||||
case WORD:
|
||||
for (keyIndex = 0;
|
||||
(p =
|
||||
sections[secIndex].items[keyIndex].id) !=
|
||||
(char *)0; keyIndex++) {
|
||||
if (strcasecmp(word->string, p) == 0) {
|
||||
CONDDEBUG((1,
|
||||
"got keyword '%s' [%s:%d]",
|
||||
word->string, file, line));
|
||||
state = VALUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (state == KEY) {
|
||||
if (isMaster)
|
||||
Error("invalid keyword '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
}
|
||||
break;
|
||||
case RIGHTBRACE:
|
||||
(*sections[secIndex].end) ();
|
||||
state = START;
|
||||
break;
|
||||
case LEFTBRACE:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case SEMICOLON:
|
||||
if (isMaster)
|
||||
Error("premature token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
case DONE: /* just shutting up gcc */
|
||||
case INCLUDE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case VALUE:
|
||||
switch (token) {
|
||||
case WORD:
|
||||
(*sections[secIndex].items[keyIndex].
|
||||
reg) (word->string);
|
||||
state = SEMI;
|
||||
break;
|
||||
case SEMICOLON:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
state = KEY;
|
||||
break;
|
||||
case RIGHTBRACE:
|
||||
if (isMaster)
|
||||
Error("premature token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
(*sections[secIndex].abort) ();
|
||||
state = START;
|
||||
break;
|
||||
case LEFTBRACE:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case DONE: /* just shutting up gcc */
|
||||
case INCLUDE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SEMI:
|
||||
switch (token) {
|
||||
case SEMICOLON:
|
||||
state = KEY;
|
||||
break;
|
||||
case RIGHTBRACE:
|
||||
if (isMaster)
|
||||
Error("premature token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
(*sections[secIndex].abort) ();
|
||||
state = START;
|
||||
break;
|
||||
case LEFTBRACE:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case WORD:
|
||||
if (isMaster)
|
||||
Error("invalid word '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case DONE: /* just shutting up gcc */
|
||||
case INCLUDE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (state) {
|
||||
case NAME:
|
||||
case VALUE:
|
||||
spaceok = 1;
|
||||
break;
|
||||
case KEY:
|
||||
case LEFTB:
|
||||
case START:
|
||||
case SEMI:
|
||||
spaceok = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
line = nextline;
|
||||
}
|
||||
|
||||
if (level == 0) {
|
||||
int i;
|
||||
|
||||
/* check for proper ending of file and do any cleanup */
|
||||
switch (state) {
|
||||
case START:
|
||||
break;
|
||||
case KEY:
|
||||
case LEFTB:
|
||||
case VALUE:
|
||||
case SEMI:
|
||||
(*sections[secIndex].abort) ();
|
||||
/* fall through */
|
||||
case NAME:
|
||||
if (isMaster)
|
||||
Error("premature EOF seen [%s:%d]", file, line);
|
||||
break;
|
||||
}
|
||||
|
||||
/* now clean up all the temporary space used */
|
||||
for (i = 0; sections[i].id != (char *)0; i++) {
|
||||
(*sections[i].destroy) ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ProcessSubst(SUBST * s, char **repl, char **str, char *name, char *id)
|
||||
#else
|
||||
ProcessSubst(s, repl, str, name, id)
|
||||
SUBST *s;
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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 (s->tokens[(unsigned)(*(repfmt[repnum]))] != ISNOTHING)
|
||||
state = REP_INT;
|
||||
else
|
||||
goto subst_err;
|
||||
break;
|
||||
case REP_INT:
|
||||
if (*p == 'd' || *p == 'x' || *p == 'X') {
|
||||
if (s->tokens[(unsigned)(*(repfmt[repnum]))] !=
|
||||
ISNUMBER)
|
||||
goto subst_err;
|
||||
state = REP_END;
|
||||
} else if (*p == 's') {
|
||||
if (s->tokens[(unsigned)(*(repfmt[repnum]))] !=
|
||||
ISSTRING)
|
||||
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 (state != REP_END) {
|
||||
subst_err:
|
||||
if (isMaster)
|
||||
Error
|
||||
("invalid `%s' specification `%s' (char #%d: `%c') [%s:%d]",
|
||||
name, id, (p - id) + 1, *p, file, line);
|
||||
return;
|
||||
}
|
||||
|
||||
if (str != (char **)0) {
|
||||
if ((*str = StrDup(id)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
|
||||
if (s != (SUBST *) 0 && repl != (char **)0) {
|
||||
static STRING *result = (STRING *)0;
|
||||
|
||||
if (result == (STRING *)0)
|
||||
result = AllocString();
|
||||
BuildString((char *)0, result);
|
||||
|
||||
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 (s->tokens[(unsigned)(*r)] == ISSTRING) {
|
||||
/* check the pattern for a length */
|
||||
if (isdigit((int)(*(r + 1))))
|
||||
plen = atoi(r + 1);
|
||||
|
||||
/* this should never return zero, but just in case */
|
||||
if ((*s->callback) (*r, &c, (int *)0) == 0)
|
||||
c = "";
|
||||
plen -= strlen(c);
|
||||
|
||||
/* pad it out, if necessary */
|
||||
for (i = 0; i < plen; i++)
|
||||
BuildStringChar(' ', result);
|
||||
|
||||
/* throw in the string */
|
||||
BuildString(c, result);
|
||||
} else {
|
||||
int i = 0;
|
||||
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);
|
||||
|
||||
/* this should never return zero, but just in case */
|
||||
if ((*s->callback) (*r, (char **)0, &i) == 0)
|
||||
port = 0;
|
||||
else
|
||||
port = (unsigned short)i;
|
||||
|
||||
/* 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();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: cutil.h,v 1.61 2004/03/10 02:55:45 bryan Exp $
|
||||
* $Id: cutil.h,v 1.63 2004/05/25 00:38:15 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -89,6 +89,37 @@ typedef struct consFile {
|
||||
#endif
|
||||
} CONSFILE;
|
||||
|
||||
typedef struct item {
|
||||
char *id;
|
||||
void (*reg) PARAMS((char *));
|
||||
} ITEM;
|
||||
|
||||
typedef struct section {
|
||||
char *id;
|
||||
void (*begin) PARAMS((char *));
|
||||
void (*end) PARAMS((void));
|
||||
void (*abort) PARAMS((void));
|
||||
void (*destroy) PARAMS((void));
|
||||
ITEM *items;
|
||||
} SECTION;
|
||||
|
||||
typedef enum substToken {
|
||||
ISNOTHING = 0,
|
||||
ISNUMBER,
|
||||
ISSTRING
|
||||
} SUBSTTOKEN;
|
||||
|
||||
typedef struct subst {
|
||||
SUBSTTOKEN tokens[255];
|
||||
/* data for callback function
|
||||
*/
|
||||
void *data;
|
||||
/* function to retrieve a value (as a char* or int or both) for
|
||||
* a substitution
|
||||
*/
|
||||
int (*callback) PARAMS((char, char **, int *));
|
||||
} SUBST;
|
||||
|
||||
extern int isMultiProc, fDebug, fVerbose, fErrorPrinted;
|
||||
extern char *progname;
|
||||
extern pid_t thepid;
|
||||
@ -100,6 +131,10 @@ extern fd_set winit;
|
||||
extern int maxfd;
|
||||
extern int debugLineNo;
|
||||
extern char *debugFileName;
|
||||
extern int line; /* used by ParseFile */
|
||||
extern char *file; /* used by ParseFile */
|
||||
extern SECTION sections[]; /* used by ParseFile */
|
||||
extern int isMaster;
|
||||
|
||||
extern const char *StrTime PARAMS((time_t *));
|
||||
extern void Debug PARAMS((int, char *, ...));
|
||||
@ -157,6 +192,10 @@ 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));
|
||||
extern void ParseFile PARAMS((char *, FILE *, int));
|
||||
extern void ProbeInterfaces PARAMS((in_addr_t));
|
||||
extern void ProcessSubst
|
||||
PARAMS((SUBST *, char **, char **, char *, char *));
|
||||
#if HAVE_OPENSSL
|
||||
extern SSL *FileGetSSL PARAMS((CONSFILE *));
|
||||
extern void FileSetSSL PARAMS((CONSFILE *, SSL *));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: group.c,v 5.298 2004/05/07 15:39:51 bryan Exp $
|
||||
* $Id: group.c,v 5.301 2004/05/25 00:38:15 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -1610,8 +1610,8 @@ PutConsole(pCEServing, c, quote)
|
||||
* quote == 2, telnet - processed by telnet protocol
|
||||
* if console != telnet, 1 == 2
|
||||
*/
|
||||
if (quote == 1 && pCEServing->type == HOST && !pCEServing->raw &&
|
||||
c == IAC) {
|
||||
if (quote == 1 && pCEServing->type == HOST &&
|
||||
pCEServing->raw != FLAGTRUE && c == IAC) {
|
||||
BuildStringChar((char)c, pCEServing->wbuf);
|
||||
if (pCEServing->wbufIAC == 0)
|
||||
pCEServing->wbufIAC = pCEServing->wbuf->used;
|
||||
@ -1685,11 +1685,11 @@ ExpandString(str, pCE, breaknum)
|
||||
++octs;
|
||||
oct = oct * 8 + (s - '0');
|
||||
continue;
|
||||
} else if (s == 'd' && pCE != (CONSENT *)0) {
|
||||
} else if (s == 'd') {
|
||||
PutConsole(pCE, IAC, 0);
|
||||
PutConsole(pCE, '0' + breaknum, 0);
|
||||
continue;
|
||||
} else if (s == 'z' && pCE != (CONSENT *)0) {
|
||||
} else if (s == 'z') {
|
||||
PutConsole(pCE, IAC, 0);
|
||||
PutConsole(pCE, BREAK, 0);
|
||||
continue;
|
||||
@ -2148,7 +2148,7 @@ CommandInfo(pGE, pCLServing, pCEServing, tyme)
|
||||
case HOST:
|
||||
FilePrint(pCLServing->fd, FLAGTRUE, "!:%s,%hu,%s",
|
||||
pCE->host, pCE->netport,
|
||||
(pCE->raw ? "raw" : "telnet"));
|
||||
(pCE->raw == FLAGTRUE ? "raw" : "telnet"));
|
||||
break;
|
||||
case DEVICE:
|
||||
FilePrint(pCLServing->fd, FLAGTRUE, "/:%s,%s%c",
|
||||
@ -2407,7 +2407,7 @@ DoConsoleRead(pCEServing)
|
||||
CONDDEBUG((1, "DoConsoleRead(): read %d bytes from fd %d", nr,
|
||||
cofile));
|
||||
|
||||
if (pCEServing->type == HOST && !pCEServing->raw) {
|
||||
if (pCEServing->type == HOST && pCEServing->raw != FLAGTRUE) {
|
||||
/* Do a little Telnet Protocol interpretation
|
||||
* state = 0: normal
|
||||
* = 1: Saw a IAC char
|
||||
@ -3933,11 +3933,19 @@ FlushConsole(pCEServing)
|
||||
}
|
||||
|
||||
if (pCEServing->wbuf->used > 1) {
|
||||
char *iac = StringChar(pCEServing->wbuf, 0, (char)IAC);
|
||||
CONDDEBUG((1, "Kiddie(): hunting for new IAC for [%s]",
|
||||
pCEServing->server));
|
||||
if (iac == (char *)0)
|
||||
pCEServing->wbufIAC = 0;
|
||||
else
|
||||
pCEServing->wbufIAC = (iac - pCEServing->wbuf->string) + 2;
|
||||
CONDDEBUG((1,
|
||||
"Kiddie(): watching writability for fd %d 'cause we have buffered data",
|
||||
FileFDNum(pCEServing->cofile)));
|
||||
FD_SET(FileFDNum(pCEServing->cofile), &winit);
|
||||
} else {
|
||||
pCEServing->wbufIAC = 0;
|
||||
if (FileBufEmpty(pCEServing->cofile)) {
|
||||
CONDDEBUG((1,
|
||||
"Kiddie(): removing writability for fd %d 'cause we don't have buffered data",
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: group.h,v 5.45 2004/05/07 03:42:49 bryan Exp $
|
||||
* $Id: group.h,v 5.46 2004/05/25 00:38:15 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -80,7 +80,6 @@ PARAMS((GRPENT *, CONSCLIENT *, char *, FLAG));
|
||||
extern int ClientAccess PARAMS((CONSENT *, char *));
|
||||
extern void DestroyClient PARAMS((CONSCLIENT *));
|
||||
extern int CheckPasswd PARAMS((CONSCLIENT *, char *));
|
||||
extern void ExpandString PARAMS((char *, CONSENT *, short));
|
||||
extern void DeUtmp PARAMS((GRPENT *, int));
|
||||
#if HAVE_OPENSSL
|
||||
extern int AttemptSSL PARAMS((CONSCLIENT *));
|
||||
|
239
conserver/main.c
239
conserver/main.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: main.c,v 5.180 2004/05/07 03:42:49 bryan Exp $
|
||||
* $Id: main.c,v 5.185 2004/05/25 23:03:01 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -40,11 +40,7 @@
|
||||
#include <readcfg.h>
|
||||
#include <version.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <dirent.h>
|
||||
#if HAVE_SYS_SOCKIO_H
|
||||
# include <sys/sockio.h>
|
||||
#endif
|
||||
#if HAVE_OPENSSL
|
||||
# include <openssl/opensslv.h>
|
||||
#endif
|
||||
@ -54,9 +50,8 @@ int fAll = 0, fNoinit = 0, fVersion = 0, fStrip = 0, fReopen =
|
||||
0, fNoautoreup = 0, fSyntaxOnly = 0;
|
||||
|
||||
char *pcConfig = CONFIGFILE;
|
||||
int isMaster = 1;
|
||||
int cMaxMemb = MAXMEMB;
|
||||
in_addr_t bindAddr;
|
||||
in_addr_t bindAddr = INADDR_ANY;
|
||||
unsigned short bindPort;
|
||||
unsigned short bindBasePort;
|
||||
static STRING *startedMsg = (STRING *)0;
|
||||
@ -603,6 +598,9 @@ Version()
|
||||
#endif
|
||||
#if TRUST_REVERSE_DNS
|
||||
"trustrevdns",
|
||||
#endif
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
"uds",
|
||||
#endif
|
||||
(char *)0
|
||||
};
|
||||
@ -651,10 +649,12 @@ Version()
|
||||
BuildStringChar('0' + DMALLOC_VERSION_MINOR, acA1);
|
||||
BuildStringChar('.', acA1);
|
||||
BuildStringChar('0' + DMALLOC_VERSION_PATCH, acA1);
|
||||
#if defined(DMALLOC_VERSION_BETA)
|
||||
if (DMALLOC_VERSION_BETA != 0) {
|
||||
BuildString("-b", acA1);
|
||||
BuildStringChar('0' + DMALLOC_VERSION_BETA, acA1);
|
||||
}
|
||||
#endif
|
||||
Msg("dmalloc version: %s", acA1->string);
|
||||
#endif
|
||||
#if HAVE_OPENSSL
|
||||
@ -720,6 +720,8 @@ DestroyDataStructures()
|
||||
DestroyBreakList();
|
||||
DestroyStrings();
|
||||
DestroyUserList();
|
||||
if (substData != (SUBST *) 0)
|
||||
free(substData);
|
||||
}
|
||||
|
||||
void
|
||||
@ -851,13 +853,13 @@ DumpDataStructures()
|
||||
GRPENT *pGE;
|
||||
CONSENT *pCE;
|
||||
REMOTE *pRC;
|
||||
char *empty = "<empty>";
|
||||
|
||||
#if HAVE_DMALLOC && DMALLOC_MARK_MAIN
|
||||
CONDDEBUG((1, "DumpDataStructures(): dmalloc / MarkMain"));
|
||||
dmalloc_log_changed(dmallocMarkMain, 1, 0, 1);
|
||||
#endif
|
||||
#define EMPTYSTR(x) x == (char *)0 ? empty : x
|
||||
#define EMPTYSTR(x) x == (char *)0 ? "(null)" : x
|
||||
#define FLAGSTR(x) x == FLAGTRUE ? "true" : (x == FLAGFALSE ? "false" : "unset")
|
||||
if (!fDebug)
|
||||
return;
|
||||
|
||||
@ -896,9 +898,9 @@ DumpDataStructures()
|
||||
"DumpDataStructures(): server=%s, type=HOST",
|
||||
EMPTYSTR(pCE->server)));
|
||||
CONDDEBUG((1,
|
||||
"DumpDataStructures(): host=%s, raw=%hu, netport=%hu, port=%hu, telnetState=%d",
|
||||
EMPTYSTR(pCE->host), pCE->raw, pCE->netport,
|
||||
pCE->port, pCE->telnetState));
|
||||
"DumpDataStructures(): host=%s, raw=%s, netport=%hu, port=%hu, telnetState=%d",
|
||||
EMPTYSTR(pCE->host), FLAGSTR(pCE->raw),
|
||||
pCE->netport, pCE->port, pCE->telnetState));
|
||||
break;
|
||||
case UNKNOWNTYPE:
|
||||
CONDDEBUG((1,
|
||||
@ -920,32 +922,27 @@ DumpDataStructures()
|
||||
CONDDEBUG((1,
|
||||
"DumpDataStructures(): mark=%d, nextMark=%ld, autoReup=%hu, downHard=%s",
|
||||
pCE->mark, pCE->nextMark, pCE->autoReUp,
|
||||
pCE->downHard == FLAGTRUE ? "true" : "false"));
|
||||
FLAGSTR(pCE->downHard)));
|
||||
CONDDEBUG((1,
|
||||
"DumpDataStructures(): nolog=%d, cofile=%d, activitylog=%s, breaklog=%s",
|
||||
pCE->nolog, FileFDNum(pCE->cofile),
|
||||
pCE->activitylog == FLAGTRUE ? "true" : "false",
|
||||
pCE->breaklog == FLAGTRUE ? "true" : "false"));
|
||||
FLAGSTR(pCE->activitylog), FLAGSTR(pCE->breaklog)));
|
||||
CONDDEBUG((1,
|
||||
"DumpDataStructures(): ixon=%s, ixany=%s, ixoff=%s",
|
||||
pCE->ixon == FLAGTRUE ? "true" : "false",
|
||||
pCE->ixany == FLAGTRUE ? "true" : "false",
|
||||
pCE->ixoff == FLAGTRUE ? "true" : "false"));
|
||||
FLAGSTR(pCE->ixon), FLAGSTR(pCE->ixany),
|
||||
FLAGSTR(pCE->ixoff)));
|
||||
CONDDEBUG((1,
|
||||
"DumpDataStructures(): autoreinit=%s, hupcl=%s, cstopb=%s, ondemand=%s",
|
||||
pCE->autoreinit == FLAGTRUE ? "true" : "false",
|
||||
pCE->hupcl == FLAGTRUE ? "true" : "false",
|
||||
pCE->cstopb == FLAGTRUE ? "true" : "false",
|
||||
pCE->ondemand == FLAGTRUE ? "true" : "false"));
|
||||
FLAGSTR(pCE->autoreinit), FLAGSTR(pCE->hupcl),
|
||||
FLAGSTR(pCE->cstopb), FLAGSTR(pCE->ondemand)));
|
||||
#if defined(CRTSCTS)
|
||||
CONDDEBUG((1, "DumpDataStructures(): crtscts=%s",
|
||||
pCE->crtscts == FLAGTRUE ? "true" : "false"));
|
||||
FLAGSTR(pCE->crtscts)));
|
||||
#endif
|
||||
CONDDEBUG((1,
|
||||
"DumpDataStructures(): reinitoncc=%s, striphigh=%s, unloved=%s",
|
||||
pCE->reinitoncc == FLAGTRUE ? "true" : "false",
|
||||
pCE->striphigh == FLAGTRUE ? "true" : "false",
|
||||
pCE->unloved == FLAGTRUE ? "true" : "false"));
|
||||
FLAGSTR(pCE->reinitoncc), FLAGSTR(pCE->striphigh),
|
||||
FLAGSTR(pCE->unloved)));
|
||||
CONDDEBUG((1,
|
||||
"DumpDataStructures(): initpid=%lu, initcmd=%s, initfile=%d",
|
||||
(unsigned long)pCE->initpid, EMPTYSTR(pCE->initcmd),
|
||||
@ -983,188 +980,6 @@ DumpDataStructures()
|
||||
}
|
||||
}
|
||||
|
||||
/* fills the myAddrs array with host interface addresses */
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ProbeInterfaces(void)
|
||||
#else
|
||||
ProbeInterfaces()
|
||||
#endif
|
||||
{
|
||||
#ifdef SIOCGIFCONF
|
||||
struct ifconf ifc;
|
||||
struct ifreq *ifr;
|
||||
#ifdef SIOCGIFFLAGS
|
||||
struct ifreq ifrcopy;
|
||||
#endif
|
||||
int sock;
|
||||
int r = 0, m = 0;
|
||||
int bufsize = 2048;
|
||||
int count = 0;
|
||||
|
||||
/* if we use -M, just fill the array with that interface */
|
||||
if (bindAddr != INADDR_ANY) {
|
||||
myAddrs = (struct in_addr *)calloc(2, sizeof(struct in_addr));
|
||||
if (myAddrs == (struct in_addr *)0)
|
||||
OutOfMem();
|
||||
#if HAVE_MEMCPY
|
||||
memcpy(&(myAddrs[0].s_addr), &bindAddr, sizeof(in_addr_t));
|
||||
#else
|
||||
bcopy(&bindAddr, &(myAddrs[0].s_addr), sizeof(in_addr_t));
|
||||
#endif
|
||||
Verbose("interface address %s (-M option)", inet_ntoa(myAddrs[0]));
|
||||
return;
|
||||
}
|
||||
|
||||
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
|
||||
Error("ProbeInterfaces(): socket(): %s", strerror(errno));
|
||||
Bye(EX_OSERR);
|
||||
}
|
||||
|
||||
while (bufsize) {
|
||||
ifc.ifc_len = bufsize;
|
||||
ifc.ifc_req = (struct ifreq *)malloc(ifc.ifc_len);
|
||||
if (ifc.ifc_req == (struct ifreq *)0)
|
||||
OutOfMem();
|
||||
if (ioctl(sock, SIOCGIFCONF, &ifc) != 0) {
|
||||
free(ifc.ifc_req);
|
||||
close(sock);
|
||||
Error("ProbeInterfaces(): ioctl(SIOCGIFCONF): %s",
|
||||
strerror(errno));
|
||||
Bye(EX_OSERR);
|
||||
}
|
||||
/* if the return size plus a 512 byte "buffer zone" is less than
|
||||
* the buffer we passed in (bufsize), we're done. otherwise
|
||||
* allocate a bigger buffer and try again. with a too-small
|
||||
* buffer, some implementations (freebsd) will fill the buffer
|
||||
* best it can (leaving a gap - returning <=bufsize) and others
|
||||
* (linux) will return a buffer length the same size as passed
|
||||
* in (==bufsize). so, we'll assume a 512 byte gap would have
|
||||
* been big enough to put one more record and as long as we have
|
||||
* that "buffer zone", we should have all the interfaces.
|
||||
*/
|
||||
if (ifc.ifc_len + 512 < bufsize)
|
||||
break;
|
||||
free(ifc.ifc_req);
|
||||
bufsize += 2048;
|
||||
}
|
||||
|
||||
/* this is probably way overkill, but better to kill a few bytes
|
||||
* than loop through looking for valid interfaces that are up
|
||||
* twice, huh?
|
||||
*/
|
||||
count = ifc.ifc_len / sizeof(*ifr);
|
||||
CONDDEBUG((1, "ProbeInterfaces(): ifc_len==%d max_count==%d",
|
||||
ifc.ifc_len, count));
|
||||
|
||||
/* set up myAddrs array */
|
||||
if (myAddrs != (struct in_addr *)0)
|
||||
free(myAddrs);
|
||||
myAddrs = (struct in_addr *)0;
|
||||
if (count == 0) {
|
||||
free(ifc.ifc_req);
|
||||
close(sock);
|
||||
return;
|
||||
}
|
||||
myAddrs = (struct in_addr *)calloc(count + 1, sizeof(struct in_addr));
|
||||
if (myAddrs == (struct in_addr *)0)
|
||||
OutOfMem();
|
||||
|
||||
for (m = r = 0; r < ifc.ifc_len;) {
|
||||
struct sockaddr *sa;
|
||||
ifr = (struct ifreq *)&ifc.ifc_buf[r];
|
||||
sa = (struct sockaddr *)&ifr->ifr_addr;
|
||||
/* don't use less than a ifreq sized chunk */
|
||||
if ((ifc.ifc_len - r) < sizeof(*ifr))
|
||||
break;
|
||||
#ifdef HAVE_SA_LEN
|
||||
if (sa->sa_len > sizeof(ifr->ifr_addr))
|
||||
r += sizeof(ifr->ifr_name) + sa->sa_len;
|
||||
else
|
||||
#endif
|
||||
r += sizeof(*ifr);
|
||||
|
||||
if (sa->sa_family == AF_INET) {
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
||||
#ifdef SIOCGIFFLAGS
|
||||
/* make sure the interface is up */
|
||||
ifrcopy = *ifr;
|
||||
if ((ioctl(sock, SIOCGIFFLAGS, &ifrcopy) == 0) &&
|
||||
((ifrcopy.ifr_flags & IFF_UP) == 0))
|
||||
continue;
|
||||
#endif
|
||||
CONDDEBUG((1, "ProbeInterfaces(): name=%s addr=%s",
|
||||
ifr->ifr_name, inet_ntoa(sin->sin_addr)));
|
||||
#if HAVE_MEMCPY
|
||||
memcpy(&myAddrs[m], &(sin->sin_addr), sizeof(struct in_addr));
|
||||
#else
|
||||
bcopy(&(sin->sin_addr), &myAddrs[m], sizeof(struct in_addr));
|
||||
#endif
|
||||
Verbose("interface address %s (%s)", inet_ntoa(myAddrs[m]),
|
||||
ifr->ifr_name);
|
||||
m++;
|
||||
}
|
||||
}
|
||||
if (m == 0) {
|
||||
free(myAddrs);
|
||||
myAddrs = (struct in_addr *)0;
|
||||
}
|
||||
close(sock);
|
||||
free(ifc.ifc_req);
|
||||
#else /* use the hostname like the old code did (but use all addresses!) */
|
||||
int count;
|
||||
struct hostent *he;
|
||||
|
||||
/* if we use -M, just fill the array with that interface */
|
||||
if (bindAddr != INADDR_ANY) {
|
||||
myAddrs = (struct in_addr *)calloc(2, sizeof(struct in_addr));
|
||||
if (myAddrs == (struct in_addr *)0)
|
||||
OutOfMem();
|
||||
#if HAVE_MEMCPY
|
||||
memcpy(&(myAddrs[0].s_addr), &bindAddr, sizeof(in_addr_t));
|
||||
#else
|
||||
bcopy(&bindAddr, &(myAddrs[0].s_addr), sizeof(in_addr_t));
|
||||
#endif
|
||||
Verbose("interface address %s (-M option)", inet_ntoa(myAddrs[0]));
|
||||
return;
|
||||
}
|
||||
|
||||
Verbose("using hostname for interface addresses");
|
||||
if ((struct hostent *)0 == (he = gethostbyname(myHostname))) {
|
||||
Error("ProbeInterfaces(): gethostbyname(%s): %s", myHostname,
|
||||
hstrerror(h_errno));
|
||||
return;
|
||||
}
|
||||
if (4 != he->h_length || AF_INET != he->h_addrtype) {
|
||||
Error
|
||||
("ProbeInterfaces(): gethostbyname(%s): wrong address size (4 != %d) or address family (%d != %d)",
|
||||
myHostname, he->h_length, AF_INET, he->h_addrtype);
|
||||
return;
|
||||
}
|
||||
|
||||
for (count = 0; he->h_addr_list[count] != (char *)0; count++);
|
||||
if (myAddrs != (struct in_addr *)0)
|
||||
free(myAddrs);
|
||||
myAddrs = (struct in_addr *)0;
|
||||
if (count == 0)
|
||||
return;
|
||||
myAddrs = (struct in_addr *)calloc(count + 1, sizeof(struct in_addr));
|
||||
if (myAddrs == (struct in_addr *)0)
|
||||
OutOfMem();
|
||||
for (count--; count >= 0; count--) {
|
||||
#if HAVE_MEMCPY
|
||||
memcpy(&(myAddrs[count].s_addr), he->h_addr_list[count],
|
||||
he->h_length);
|
||||
#else
|
||||
bcopy(he->h_addr_list[count], &(myAddrs[count].s_addr),
|
||||
he->h_length);
|
||||
#endif
|
||||
Verbose("interface address %s (hostname address)",
|
||||
inet_ntoa(myAddrs[count]));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This makes sure a directory exists and tries to create it if it
|
||||
* doesn't. returns 0 for success, -1 for error
|
||||
*/
|
||||
@ -1290,9 +1105,9 @@ main(argc, argv)
|
||||
|
||||
thepid = getpid();
|
||||
if ((char *)0 == (progname = strrchr(argv[0], '/'))) {
|
||||
progname = StrDup(argv[0]);
|
||||
progname = argv[0];
|
||||
} else {
|
||||
progname = StrDup(++progname);
|
||||
++progname;
|
||||
}
|
||||
|
||||
setpwent();
|
||||
@ -1354,7 +1169,7 @@ main(argc, argv)
|
||||
#endif
|
||||
break;
|
||||
case 'C':
|
||||
pcConfig = StrDup(optarg);
|
||||
pcConfig = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
optConf->daemonmode = FLAGTRUE;
|
||||
@ -1520,7 +1335,7 @@ main(argc, argv)
|
||||
Error("gethostname(): %s", strerror(errno));
|
||||
Bye(EX_OSERR);
|
||||
}
|
||||
ProbeInterfaces();
|
||||
ProbeInterfaces(bindAddr);
|
||||
|
||||
/* initialize the timers */
|
||||
for (i = 0; i < T_MAX; i++)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: main.h,v 5.52 2004/04/13 18:12:00 bryan Exp $
|
||||
* $Id: main.h,v 5.53 2004/05/21 04:15:17 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -44,7 +44,6 @@ extern unsigned short bindPort, bindBasePort;
|
||||
extern char *pcConfig;
|
||||
extern int cMaxMemb;
|
||||
extern struct sockaddr_in in_port;
|
||||
extern int isMaster;
|
||||
extern CONFIG *optConf;
|
||||
extern CONFIG *config;
|
||||
extern CONFIG defConfig;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: readcfg.c,v 5.173 2004/05/07 03:42:49 bryan Exp $
|
||||
* $Id: readcfg.c,v 5.176 2004/05/25 00:38:15 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -123,24 +123,8 @@ AddUserList(id)
|
||||
}
|
||||
|
||||
/***** internal things *****/
|
||||
typedef struct item {
|
||||
char *id;
|
||||
void (*reg) PARAMS((char *));
|
||||
} ITEM;
|
||||
|
||||
typedef struct section {
|
||||
char *id;
|
||||
void (*begin) PARAMS((char *));
|
||||
void (*end) PARAMS((void));
|
||||
void (*abort) PARAMS((void));
|
||||
void (*destroy) PARAMS((void));
|
||||
ITEM *items;
|
||||
} SECTION;
|
||||
|
||||
#define ALLWORDSEP ", \f\v\t\n\r"
|
||||
|
||||
int line = 1; /* current line number */
|
||||
char *file = (char *)0;
|
||||
int isStartup = 0;
|
||||
GRPENT *pGroupsOld = (GRPENT *)0;
|
||||
GRPENT *pGEstage = (GRPENT *)0;
|
||||
@ -681,6 +665,8 @@ ApplyDefault(d, c)
|
||||
c->idletimeout = d->idletimeout;
|
||||
if (d->logfilemax != 0)
|
||||
c->logfilemax = d->logfilemax;
|
||||
if (d->raw != FLAGUNKNOWN)
|
||||
c->raw = d->raw;
|
||||
if (d->port != 0)
|
||||
c->port = d->port;
|
||||
if (d->netport != 0)
|
||||
@ -975,239 +961,6 @@ ProcessDevice(c, id)
|
||||
OutOfMem();
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ProcessSubst(CONSENT *pCE, char **repl, char **str, char *name, char *id)
|
||||
#else
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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 (state != REP_END) {
|
||||
subst_err:
|
||||
if (isMaster)
|
||||
Error
|
||||
("invalid `%s' specification `%s' (char #%d: `%c') [%s:%d]",
|
||||
name, id, (p - id) + 1, *p, file, line);
|
||||
return;
|
||||
}
|
||||
|
||||
if (str != (char **)0) {
|
||||
if ((*str = StrDup(id)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
|
||||
if (pCE != (CONSENT *)0 && repl != (char **)0) {
|
||||
static STRING *result = (STRING *)0;
|
||||
|
||||
if (result == (STRING *)0)
|
||||
result = AllocString();
|
||||
BuildString((char *)0, result);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
DefaultItemDevice(char *id)
|
||||
@ -1220,6 +973,63 @@ DefaultItemDevice(id)
|
||||
ProcessDevice(parserDefaultTemp, id);
|
||||
}
|
||||
|
||||
SUBST *substData = (SUBST *) 0;
|
||||
|
||||
int
|
||||
#if PROTOTYPES
|
||||
SubstCallback(char c, char **s, int *i)
|
||||
#else
|
||||
SubstCallback(c, s, i)
|
||||
char c;
|
||||
char **s;
|
||||
int *i;
|
||||
#endif
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
if (substData == (SUBST *) 0) {
|
||||
if ((substData =
|
||||
(SUBST *) calloc(1, sizeof(SUBST))) == (SUBST *) 0)
|
||||
OutOfMem();
|
||||
substData->callback = &SubstCallback;
|
||||
substData->tokens['p'] = ISNUMBER;
|
||||
substData->tokens['P'] = ISNUMBER;
|
||||
substData->tokens['h'] = ISSTRING;
|
||||
substData->tokens['c'] = ISSTRING;
|
||||
}
|
||||
|
||||
if (s != (char **)0) {
|
||||
CONSENT *pCE;
|
||||
if (substData->data == (void *)0)
|
||||
return 0;
|
||||
|
||||
pCE = (CONSENT *)(substData->data);
|
||||
if (c == 'h') {
|
||||
(*s) = pCE->host;
|
||||
retval = 1;
|
||||
} else if (c == 'c') {
|
||||
(*s) = pCE->server;
|
||||
retval = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (i != (int *)0) {
|
||||
CONSENT *pCE;
|
||||
if (substData->data == (void *)0)
|
||||
return 0;
|
||||
pCE = (CONSENT *)(substData->data);
|
||||
if (c == 'p') {
|
||||
(*i) = pCE->port;
|
||||
retval = 1;
|
||||
} else if (c == 'P') {
|
||||
(*i) = pCE->netport;
|
||||
retval = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
DefaultItemDevicesubst(char *id)
|
||||
@ -1229,8 +1039,8 @@ DefaultItemDevicesubst(id)
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "DefaultItemDevicesubst(%s) [%s:%d]", id, file, line));
|
||||
ProcessSubst((CONSENT *)0, (char **)0,
|
||||
&(parserDefaultTemp->devicesubst), "devicesubst", id);
|
||||
ProcessSubst(substData, (char **)0, &(parserDefaultTemp->devicesubst),
|
||||
"devicesubst", id);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1242,7 +1052,7 @@ DefaultItemExecsubst(id)
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "DefaultItemExecsubst(%s) [%s:%d]", id, file, line));
|
||||
ProcessSubst((CONSENT *)0, (char **)0, &(parserDefaultTemp->execsubst),
|
||||
ProcessSubst(substData, (char **)0, &(parserDefaultTemp->execsubst),
|
||||
"execsubst", id);
|
||||
}
|
||||
|
||||
@ -1255,7 +1065,7 @@ DefaultItemInitsubst(id)
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "DefaultItemInitsubst(%s) [%s:%d]", id, file, line));
|
||||
ProcessSubst((CONSENT *)0, (char **)0, &(parserDefaultTemp->initsubst),
|
||||
ProcessSubst(substData, (char **)0, &(parserDefaultTemp->initsubst),
|
||||
"initsubst", id);
|
||||
}
|
||||
|
||||
@ -1859,14 +1669,17 @@ ProcessProtocol(c, id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
c->raw = 0;
|
||||
if ((id == (char *)0) || (*id == '\000'))
|
||||
if ((id == (char *)0) || (*id == '\000')) {
|
||||
c->raw = FLAGUNKNOWN;
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(id, "telnet") == 0)
|
||||
if (strcmp(id, "telnet") == 0) {
|
||||
c->raw = FLAGFALSE;
|
||||
return;
|
||||
}
|
||||
if (strcmp(id, "raw") == 0) {
|
||||
c->raw = 1;
|
||||
c->raw = FLAGTRUE;
|
||||
return;
|
||||
}
|
||||
if (isMaster)
|
||||
@ -2850,6 +2663,7 @@ ConsoleAdd(c)
|
||||
pCEmatch->portbase = c->portbase;
|
||||
pCEmatch->activitylog = c->activitylog;
|
||||
pCEmatch->breaklog = c->breaklog;
|
||||
pCEmatch->raw = c->raw;
|
||||
pCEmatch->mark = c->mark;
|
||||
pCEmatch->nextMark = c->nextMark;
|
||||
pCEmatch->breakNum = c->breakNum;
|
||||
@ -2962,17 +2776,18 @@ ConsoleDestroy()
|
||||
*/
|
||||
c->netport = c->portbase + c->portinc * c->port;
|
||||
|
||||
substData->data = (void *)c;
|
||||
/* check for substitutions */
|
||||
if (c->type == DEVICE && c->devicesubst != (char *)0)
|
||||
ProcessSubst(c, &(c->device), (char **)0, (char *)0,
|
||||
ProcessSubst(substData, &(c->device), (char **)0, (char *)0,
|
||||
c->devicesubst);
|
||||
|
||||
if (c->type == EXEC && c->execsubst != (char *)0)
|
||||
ProcessSubst(c, &(c->exec), (char **)0, (char *)0,
|
||||
ProcessSubst(substData, &(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,
|
||||
ProcessSubst(substData, &(c->initcmd), (char **)0, (char *)0,
|
||||
c->initsubst);
|
||||
|
||||
/* go ahead and do the '&' substitution */
|
||||
@ -3003,6 +2818,8 @@ ConsoleDestroy()
|
||||
/* set the options that default false */
|
||||
if (c->activitylog == FLAGUNKNOWN)
|
||||
c->activitylog = FLAGFALSE;
|
||||
if (c->raw == FLAGUNKNOWN)
|
||||
c->raw = FLAGFALSE;
|
||||
if (c->breaklog == FLAGUNKNOWN)
|
||||
c->breaklog = FLAGFALSE;
|
||||
if (c->hupcl == FLAGUNKNOWN)
|
||||
@ -3274,8 +3091,8 @@ ConsoleItemDevicesubst(id)
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "ConsoleItemDevicesubst(%s) [%s:%d]", id, file, line));
|
||||
ProcessSubst((CONSENT *)0, (char **)0,
|
||||
&(parserConsoleTemp->devicesubst), "devicesubst", id);
|
||||
ProcessSubst(substData, (char **)0, &(parserConsoleTemp->devicesubst),
|
||||
"devicesubst", id);
|
||||
}
|
||||
|
||||
void
|
||||
@ -3287,7 +3104,7 @@ ConsoleItemExecsubst(id)
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "ConsoleItemExecsubst(%s) [%s:%d]", id, file, line));
|
||||
ProcessSubst((CONSENT *)0, (char **)0, &(parserConsoleTemp->execsubst),
|
||||
ProcessSubst(substData, (char **)0, &(parserConsoleTemp->execsubst),
|
||||
"execsubst", id);
|
||||
}
|
||||
|
||||
@ -3300,7 +3117,7 @@ ConsoleItemInitsubst(id)
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "ConsoleItemInitsubst(%s) [%s:%d]", id, file, line));
|
||||
ProcessSubst((CONSENT *)0, (char **)0, &(parserConsoleTemp->initsubst),
|
||||
ProcessSubst(substData, (char **)0, &(parserConsoleTemp->initsubst),
|
||||
"initsubst", id);
|
||||
}
|
||||
|
||||
@ -4595,484 +4412,6 @@ SECTION sections[] = {
|
||||
{(char *)0, (void *)0, (void *)0, (void *)0, (void *)0}
|
||||
};
|
||||
|
||||
/* the format of the file should be as follows
|
||||
*
|
||||
* <section keyword> [section name] {
|
||||
* <item keyword> [item value];
|
||||
* .
|
||||
* .
|
||||
* }
|
||||
*
|
||||
* whitespace gets retained in [section name], and [item value]
|
||||
* values. for example,
|
||||
*
|
||||
* users bryan todd ;
|
||||
*
|
||||
* will give users the value of 'bryan todd'. the leading and
|
||||
* trailing whitespace is nuked, but the middle stuff isn't.
|
||||
*
|
||||
* a little note about the 'state' var...
|
||||
* START = before <section keyword>
|
||||
* NAME = before [section name]
|
||||
* LEFTB = before left curly brace
|
||||
* KEY = before <item keyword>
|
||||
* VALUE = before [item value]
|
||||
* SEMI = before semi-colon
|
||||
*/
|
||||
|
||||
typedef enum states {
|
||||
START,
|
||||
NAME,
|
||||
LEFTB,
|
||||
KEY,
|
||||
VALUE,
|
||||
SEMI
|
||||
} STATES;
|
||||
|
||||
typedef enum tokens {
|
||||
DONE,
|
||||
LEFTBRACE,
|
||||
RIGHTBRACE,
|
||||
SEMICOLON,
|
||||
WORD,
|
||||
INCLUDE
|
||||
} TOKEN;
|
||||
|
||||
TOKEN
|
||||
#if PROTOTYPES
|
||||
GetWord(FILE *fp, int *line, short spaceok, STRING *word)
|
||||
#else
|
||||
GetWord(fp, line, spaceok, word)
|
||||
FILE *fp;
|
||||
int *line;
|
||||
short spaceok;
|
||||
STRING *word;
|
||||
#endif
|
||||
{
|
||||
int c;
|
||||
short backslash = 0;
|
||||
short quote = 0;
|
||||
short comment = 0;
|
||||
short sawQuote = 0;
|
||||
short quotedBackslash = 0;
|
||||
char *include = "include";
|
||||
short checkInc = -1;
|
||||
/* checkInc == -3, saw #include
|
||||
* == -2, saw nothin'
|
||||
* == -1, saw \n or start of file
|
||||
* == 0, saw "\n#"
|
||||
*/
|
||||
|
||||
BuildString((char *)0, word);
|
||||
while ((c = fgetc(fp)) != EOF) {
|
||||
if (c == '\n') {
|
||||
(*line)++;
|
||||
if (checkInc == -2)
|
||||
checkInc = -1;
|
||||
}
|
||||
if (comment) {
|
||||
if (c == '\n')
|
||||
comment = 0;
|
||||
if (checkInc >= 0) {
|
||||
if (include[checkInc] == '\000') {
|
||||
if (isspace(c))
|
||||
checkInc = -3;
|
||||
} else if (c == include[checkInc])
|
||||
checkInc++;
|
||||
else
|
||||
checkInc = -2;
|
||||
} else if (checkInc == -3) {
|
||||
static STRING *fname = (STRING *)0;
|
||||
if (fname == (STRING *)0)
|
||||
fname = AllocString();
|
||||
if (fname->used != 0 || !isspace(c)) {
|
||||
if (c == '\n') {
|
||||
if (fname->used > 0) {
|
||||
while (fname->used > 1 && isspace((int)
|
||||
(fname->
|
||||
string
|
||||
[fname->
|
||||
used -
|
||||
2])))
|
||||
fname->used--;
|
||||
if (fname->used > 0)
|
||||
fname->string[fname->used - 1] = '\000';
|
||||
}
|
||||
checkInc = -2;
|
||||
if (fname->used > 0) {
|
||||
BuildString((char *)0, word);
|
||||
BuildString(fname->string, word);
|
||||
BuildString((char *)0, fname);
|
||||
return INCLUDE;
|
||||
}
|
||||
} else
|
||||
BuildStringChar(c, fname);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (backslash) {
|
||||
BuildStringChar(c, word);
|
||||
backslash = 0;
|
||||
continue;
|
||||
}
|
||||
if (quote) {
|
||||
if (c == '"') {
|
||||
if (quotedBackslash) {
|
||||
BuildStringChar(c, word);
|
||||
quotedBackslash = 0;
|
||||
} else
|
||||
quote = 0;
|
||||
} else {
|
||||
if (quotedBackslash) {
|
||||
BuildStringChar('\\', word);
|
||||
quotedBackslash = 0;
|
||||
}
|
||||
if (c == '\\')
|
||||
quotedBackslash = 1;
|
||||
else
|
||||
BuildStringChar(c, word);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (c == '\\') {
|
||||
backslash = 1;
|
||||
} else if (c == '#') {
|
||||
comment = 1;
|
||||
if (checkInc == -1)
|
||||
checkInc = 0;
|
||||
} else if (c == '"') {
|
||||
quote = 1;
|
||||
sawQuote = 1;
|
||||
} else if (isspace(c)) {
|
||||
if (word->used <= 1)
|
||||
continue;
|
||||
if (spaceok) {
|
||||
BuildStringChar(c, word);
|
||||
continue;
|
||||
}
|
||||
gotword:
|
||||
while (word->used > 1 &&
|
||||
isspace((int)(word->string[word->used - 2])))
|
||||
word->used--;
|
||||
if (word->used > 0)
|
||||
word->string[word->used - 1] = '\000';
|
||||
return WORD;
|
||||
} else if (c == '{') {
|
||||
if (word->used <= 1 && !sawQuote) {
|
||||
BuildStringChar(c, word);
|
||||
return LEFTBRACE;
|
||||
} else {
|
||||
ungetc(c, fp);
|
||||
goto gotword;
|
||||
}
|
||||
} else if (c == '}') {
|
||||
if (word->used <= 1 && !sawQuote) {
|
||||
BuildStringChar(c, word);
|
||||
return RIGHTBRACE;
|
||||
} else {
|
||||
ungetc(c, fp);
|
||||
goto gotword;
|
||||
}
|
||||
} else if (c == ';') {
|
||||
if (word->used <= 1 && !sawQuote) {
|
||||
BuildStringChar(c, word);
|
||||
return SEMICOLON;
|
||||
} else {
|
||||
ungetc(c, fp);
|
||||
goto gotword;
|
||||
}
|
||||
} else {
|
||||
BuildStringChar(c, word);
|
||||
}
|
||||
}
|
||||
/* this should only happen in rare cases */
|
||||
if (quotedBackslash) {
|
||||
BuildStringChar('\\', word);
|
||||
quotedBackslash = 0;
|
||||
}
|
||||
/* if we saw "valid" data, it's a word */
|
||||
if (word->used > 1 || sawQuote)
|
||||
goto gotword;
|
||||
return DONE;
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ParseFile(char *filename, FILE *fp, int level)
|
||||
#else
|
||||
ParseFile(filename, fp, level)
|
||||
char *filename;
|
||||
FILE *fp;
|
||||
int level;
|
||||
#endif
|
||||
{
|
||||
/* things that should be used between recursions */
|
||||
static STATES state = START;
|
||||
static STRING *word = (STRING *)0;
|
||||
static short spaceok = 0;
|
||||
static int secIndex = 0;
|
||||
static int keyIndex = 0;
|
||||
|
||||
/* other stuff that's local to each recursion */
|
||||
char *p;
|
||||
TOKEN token = DONE;
|
||||
int nextline = 1; /* "next" line number */
|
||||
|
||||
if (level >= 10) {
|
||||
if (isMaster)
|
||||
Error("ParseFile(): nesting too deep, not parsing `%s'",
|
||||
filename);
|
||||
return;
|
||||
}
|
||||
|
||||
/* set some globals */
|
||||
line = 1;
|
||||
file = filename;
|
||||
|
||||
/* if we're parsing the base file, set static vars */
|
||||
if (level == 0) {
|
||||
state = START;
|
||||
spaceok = 0;
|
||||
secIndex = 0;
|
||||
keyIndex = 0;
|
||||
}
|
||||
|
||||
/* initialize local things */
|
||||
if (word == (STRING *)0)
|
||||
word = AllocString();
|
||||
|
||||
while ((token = GetWord(fp, &nextline, spaceok, word)) != DONE) {
|
||||
if (token == INCLUDE) {
|
||||
FILE *lfp;
|
||||
if ((FILE *)0 == (lfp = fopen(word->string, "r"))) {
|
||||
if (isMaster)
|
||||
Error("ParseFile(): fopen(%s): %s", word->string,
|
||||
strerror(errno));
|
||||
} else {
|
||||
char *fname;
|
||||
/* word gets destroyed, so save the name */
|
||||
fname = StrDup(word->string);
|
||||
ParseFile(fname, lfp, level + 1);
|
||||
fclose(lfp);
|
||||
free(fname);
|
||||
}
|
||||
} else {
|
||||
switch (state) {
|
||||
case START:
|
||||
switch (token) {
|
||||
case WORD:
|
||||
for (secIndex = 0;
|
||||
(p = sections[secIndex].id) != (char *)0;
|
||||
secIndex++) {
|
||||
if (strcasecmp(word->string, p) == 0) {
|
||||
CONDDEBUG((1,
|
||||
"ReadCfg(): got keyword '%s' [%s:%d]",
|
||||
word->string, file, line));
|
||||
state = NAME;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (state == START) {
|
||||
if (isMaster)
|
||||
Error("invalid keyword '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
}
|
||||
break;
|
||||
case LEFTBRACE:
|
||||
case RIGHTBRACE:
|
||||
case SEMICOLON:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case DONE: /* just shutting up gcc */
|
||||
case INCLUDE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NAME:
|
||||
switch (token) {
|
||||
case WORD:
|
||||
(*sections[secIndex].begin) (word->string);
|
||||
state = LEFTB;
|
||||
break;
|
||||
case RIGHTBRACE:
|
||||
if (isMaster)
|
||||
Error("premature token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
state = START;
|
||||
break;
|
||||
case LEFTBRACE:
|
||||
case SEMICOLON:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case DONE: /* just shutting up gcc */
|
||||
case INCLUDE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case LEFTB:
|
||||
switch (token) {
|
||||
case LEFTBRACE:
|
||||
state = KEY;
|
||||
break;
|
||||
case RIGHTBRACE:
|
||||
if (isMaster)
|
||||
Error("premature token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
(*sections[secIndex].abort) ();
|
||||
state = START;
|
||||
break;
|
||||
case SEMICOLON:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case WORD:
|
||||
if (isMaster)
|
||||
Error("invalid word '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case DONE: /* just shutting up gcc */
|
||||
case INCLUDE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case KEY:
|
||||
switch (token) {
|
||||
case WORD:
|
||||
for (keyIndex = 0;
|
||||
(p =
|
||||
sections[secIndex].items[keyIndex].id) !=
|
||||
(char *)0; keyIndex++) {
|
||||
if (strcasecmp(word->string, p) == 0) {
|
||||
CONDDEBUG((1,
|
||||
"got keyword '%s' [%s:%d]",
|
||||
word->string, file, line));
|
||||
state = VALUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (state == KEY) {
|
||||
if (isMaster)
|
||||
Error("invalid keyword '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
}
|
||||
break;
|
||||
case RIGHTBRACE:
|
||||
(*sections[secIndex].end) ();
|
||||
state = START;
|
||||
break;
|
||||
case LEFTBRACE:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case SEMICOLON:
|
||||
if (isMaster)
|
||||
Error("premature token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
case DONE: /* just shutting up gcc */
|
||||
case INCLUDE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case VALUE:
|
||||
switch (token) {
|
||||
case WORD:
|
||||
(*sections[secIndex].items[keyIndex].
|
||||
reg) (word->string);
|
||||
state = SEMI;
|
||||
break;
|
||||
case SEMICOLON:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
state = KEY;
|
||||
break;
|
||||
case RIGHTBRACE:
|
||||
if (isMaster)
|
||||
Error("premature token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
(*sections[secIndex].abort) ();
|
||||
state = START;
|
||||
break;
|
||||
case LEFTBRACE:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case DONE: /* just shutting up gcc */
|
||||
case INCLUDE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SEMI:
|
||||
switch (token) {
|
||||
case SEMICOLON:
|
||||
state = KEY;
|
||||
break;
|
||||
case RIGHTBRACE:
|
||||
if (isMaster)
|
||||
Error("premature token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
(*sections[secIndex].abort) ();
|
||||
state = START;
|
||||
break;
|
||||
case LEFTBRACE:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case WORD:
|
||||
if (isMaster)
|
||||
Error("invalid word '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case DONE: /* just shutting up gcc */
|
||||
case INCLUDE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (state) {
|
||||
case NAME:
|
||||
case VALUE:
|
||||
spaceok = 1;
|
||||
break;
|
||||
case KEY:
|
||||
case LEFTB:
|
||||
case START:
|
||||
case SEMI:
|
||||
spaceok = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
line = nextline;
|
||||
}
|
||||
|
||||
if (level == 0) {
|
||||
/* check for proper ending of file and do any cleanup */
|
||||
switch (state) {
|
||||
case START:
|
||||
break;
|
||||
case KEY:
|
||||
case LEFTB:
|
||||
case VALUE:
|
||||
case SEMI:
|
||||
(*sections[secIndex].abort) ();
|
||||
/* fall through */
|
||||
case NAME:
|
||||
if (isMaster)
|
||||
Error("premature EOF seen [%s:%d]", file, line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ReadCfg(char *filename, FILE *fp)
|
||||
@ -5082,7 +4421,6 @@ ReadCfg(filename, fp)
|
||||
FILE *fp;
|
||||
#endif
|
||||
{
|
||||
char *p;
|
||||
int i;
|
||||
#if HAVE_DMALLOC && DMALLOC_MARK_READCFG
|
||||
unsigned long dmallocMarkReadCfg = 0;
|
||||
@ -5116,18 +4454,15 @@ ReadCfg(filename, fp)
|
||||
DestroyConfig(pConfig);
|
||||
pConfig = (CONFIG *)0;
|
||||
}
|
||||
if ((pConfig = (CONFIG *)calloc(1, sizeof(CONFIG)))
|
||||
== (CONFIG *)0)
|
||||
if ((pConfig = (CONFIG *)calloc(1, sizeof(CONFIG))) == (CONFIG *)0)
|
||||
OutOfMem();
|
||||
|
||||
/* initialize the substition bits */
|
||||
SubstCallback('\000', (char **)0, (int *)0);
|
||||
|
||||
/* ready to read in the data */
|
||||
ParseFile(filename, fp, 0);
|
||||
|
||||
/* now clean up all the temporary space used */
|
||||
for (i = 0; (p = sections[i].id) != (char *)0; i++) {
|
||||
(*sections[i].destroy) ();
|
||||
}
|
||||
|
||||
#if HAVE_DMALLOC && DMALLOC_MARK_READCFG
|
||||
CONDDEBUG((1, "ReadCfg(): dmalloc / MarkReadCfg"));
|
||||
dmalloc_log_changed(dmallocMarkReadCfg, 1, 0, 1);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: readcfg.h,v 5.39 2004/05/07 03:42:49 bryan Exp $
|
||||
* $Id: readcfg.h,v 5.40 2004/05/25 23:03:01 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -43,6 +43,7 @@ extern ACCESS *pACList; /* `who do you love' (or trust) */
|
||||
extern CONSENTUSERS *pADList; /* list of admin users */
|
||||
extern BREAKS breakList[9]; /* list of break sequences */
|
||||
extern CONFIG *pConfig; /* settings seen by config parser */
|
||||
extern SUBST *substData; /* substitution function data */
|
||||
|
||||
extern void ReadCfg PARAMS((char *, FILE *));
|
||||
extern void ReReadCfg PARAMS((int));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: version.h,v 1.61 2004/04/16 16:58:09 bryan Exp $
|
||||
* $Id: version.h,v 1.62 2004/05/23 16:44:45 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.1.5"
|
||||
#define THIS_VERSION "conserver.com version 8.1.6"
|
||||
|
@ -25,11 +25,11 @@ LIBS = @LIBS@
|
||||
|
||||
### Makefile rules - no user-servicable parts below
|
||||
|
||||
CONSOLE_OBJS = console.o getpassword.o ../conserver/cutil.o
|
||||
CONSOLE_OBJS = console.o getpassword.o readconf.o ../conserver/cutil.o
|
||||
CONSOLE_HDRS = ../config.h $(top_srcdir)/compat.h \
|
||||
$(top_srcdir)/conserver/cutil.h \
|
||||
$(top_srcdir)/conserver/version.h \
|
||||
$(srcdir)/getpassword.h
|
||||
$(srcdir)/getpassword.h $(srcdir)/readconf.h
|
||||
ALL = console
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: console.c,v 5.164 2004/04/20 01:30:13 bryan Exp $
|
||||
* $Id: console.c,v 5.167 2004/05/25 23:03:25 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -34,6 +34,7 @@
|
||||
#include <getpassword.h>
|
||||
#include <cutil.h>
|
||||
#include <version.h>
|
||||
#include <readconf.h>
|
||||
#if HAVE_OPENSSL
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
@ -41,24 +42,11 @@
|
||||
#endif
|
||||
|
||||
|
||||
int fReplay = 0, fVersion = 0, fStrip = 0;
|
||||
int fReplay = 0, fVersion = 0;
|
||||
int showExecData = 1;
|
||||
#if HAVE_OPENSSL
|
||||
int fReqEncryption = 1;
|
||||
int fAllowUnencrypted = 0;
|
||||
char *pcCredFile = (char *)0;
|
||||
#endif
|
||||
int chAttn = -1, chEsc = -1;
|
||||
char *pcInMaster =
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
UDSDIR;
|
||||
#else
|
||||
MASTERHOST; /* which machine is current */
|
||||
#endif
|
||||
char *pcPort = DEFPORT;
|
||||
unsigned short bindPort;
|
||||
CONSFILE *cfstdout;
|
||||
char *pcUser = (char *)0;
|
||||
int disconnectCount = 0;
|
||||
STRING *execCmd = (STRING *)0;
|
||||
CONSFILE *execCmdFile = (CONSFILE *)0;
|
||||
@ -67,6 +55,8 @@ CONSFILE *gotoConsole = (CONSFILE *)0;
|
||||
CONSFILE *prevConsole = (CONSFILE *)0;
|
||||
char *gotoName = (char *)0;
|
||||
char *prevName = (char *)0;
|
||||
CONFIG *optConf = (CONFIG *)0;
|
||||
CONFIG *config = (CONFIG *)0;
|
||||
|
||||
#if HAVE_OPENSSL
|
||||
SSL_CTX *ctx = (SSL_CTX *)0;
|
||||
@ -92,15 +82,17 @@ SetupSSL()
|
||||
Error("Could not load SSL default CA file and/or directory");
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
if (pcCredFile != (char *)0) {
|
||||
if (SSL_CTX_use_certificate_chain_file(ctx, pcCredFile) != 1) {
|
||||
if (config->sslcredentials != (char *)0) {
|
||||
if (SSL_CTX_use_certificate_chain_file
|
||||
(ctx, config->sslcredentials) != 1) {
|
||||
Error("Could not load SSL certificate from '%s'",
|
||||
pcCredFile);
|
||||
config->sslcredentials);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
if (SSL_CTX_use_PrivateKey_file
|
||||
(ctx, pcCredFile, SSL_FILETYPE_PEM) != 1) {
|
||||
Error("Could not SSL private key from '%s'", pcCredFile);
|
||||
(ctx, config->sslcredentials, SSL_FILETYPE_PEM) != 1) {
|
||||
Error("Could not SSL private key from '%s'",
|
||||
config->sslcredentials);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
@ -191,54 +183,56 @@ Usage(wantfull)
|
||||
#endif
|
||||
{
|
||||
static char *full[] = {
|
||||
"7 strip the high bit off all console data",
|
||||
"a(A) attach politely (and replay last 20 lines)",
|
||||
"b(B) send broadcast message to all users (on master)",
|
||||
"7 strip the high bit off all console data",
|
||||
"a(A) attach politely (and replay last 20 lines)",
|
||||
"b(B) send broadcast message to all users (on master)",
|
||||
#if HAVE_OPENSSL
|
||||
"c cred load an SSL certificate and key from the PEM encoded file",
|
||||
"c cred load an SSL certificate and key from the PEM encoded file",
|
||||
#else
|
||||
"c cred ignored - encryption not compiled into code",
|
||||
"c cred ignored - encryption not compiled into code",
|
||||
#endif
|
||||
"d disconnect [user][@console]",
|
||||
"D enable debug output, sent to stderr",
|
||||
"e esc set the initial escape characters",
|
||||
"C config override per-user config file",
|
||||
"d disconnect [user][@console]",
|
||||
"D enable debug output, sent to stderr",
|
||||
"e esc set the initial escape characters",
|
||||
#if HAVE_OPENSSL
|
||||
"E don't attempt encrypted connections",
|
||||
"E don't attempt encrypted connections",
|
||||
#else
|
||||
"E ignored - encryption not compiled into code",
|
||||
"E ignored - encryption not compiled into code",
|
||||
#endif
|
||||
"f(F) force read/write connection (and replay)",
|
||||
"h output this message",
|
||||
"i(I) display information in machine-parseable form (on master)",
|
||||
"l user use username instead of current username",
|
||||
"M mach master server to poll first",
|
||||
"p port port to connect to",
|
||||
"P display pids of daemon(s)",
|
||||
"q(Q) send a quit command to the (master) server",
|
||||
"r(R) display (master) daemon version (think 'r'emote version)",
|
||||
"s(S) spy on a console (and replay)",
|
||||
"t send a text message to [user][@console]",
|
||||
"u show users on the various consoles",
|
||||
"f(F) force read/write connection (and replay)",
|
||||
"h output this message",
|
||||
"i(I) display information in machine-parseable form (on master)",
|
||||
"l user use username instead of current username",
|
||||
"M master master server to poll first",
|
||||
"n do not read system-wide config file",
|
||||
"p port port to connect to",
|
||||
"P display pids of daemon(s)",
|
||||
"q(Q) send a quit command to the (master) server",
|
||||
"r(R) display (master) daemon version (think 'r'emote version)",
|
||||
"s(S) spy on a console (and replay)",
|
||||
"t send a text message to [user][@console]",
|
||||
"u show users on the various consoles",
|
||||
#if HAVE_OPENSSL
|
||||
"U allow unencrypted connections if SSL not available",
|
||||
"U allow unencrypted connections if SSL not available",
|
||||
#else
|
||||
"U ignored - encryption not compiled into code",
|
||||
"U ignored - encryption not compiled into code",
|
||||
#endif
|
||||
"v be more verbose",
|
||||
"V show version information",
|
||||
"w(W) show who is on which console (on master)",
|
||||
"x examine ports and baud rates",
|
||||
"v be more verbose",
|
||||
"V show version information",
|
||||
"w(W) show who is on which console (on master)",
|
||||
"x examine ports and baud rates",
|
||||
(char *)0
|
||||
};
|
||||
|
||||
fprintf(stderr,
|
||||
"usage: %s [-aAfFsS] [-7DEUv] [-c cred] [-M mach] [-p port] [-e esc] [-l username] console\n",
|
||||
"usage: %s [-aAfFsS] [-7DEnUv] [-c cred] [-C config] [-M master] [-p port] [-e esc] [-l username] console\n",
|
||||
progname);
|
||||
fprintf(stderr,
|
||||
" %s [-hiIPrRuVwWx] [-7DEUv] [-c cred] [-M mach] [-p port] [-d [user][@console]] [-[bB] message] [-t [user][@console] message]\n",
|
||||
" %s [-hiIPrRuVwWx] [-7DEnUv] [-c cred] [-C config] [-M master] [-p port] [-d [user][@console]] [-[bB] message] [-t [user][@console] message]\n",
|
||||
progname);
|
||||
fprintf(stderr,
|
||||
" %s [-qQ] [-7DEUv] [-c cred] [-M mach] [-p port]\n",
|
||||
" %s [-qQ] [-7DEnUv] [-c cred] [-C config] [-M master] [-p port]\n",
|
||||
progname);
|
||||
|
||||
if (wantfull) {
|
||||
@ -272,6 +266,9 @@ Version()
|
||||
#endif
|
||||
#if HAVE_PAM
|
||||
"pam",
|
||||
#endif
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
"uds",
|
||||
#endif
|
||||
(char *)0
|
||||
};
|
||||
@ -290,6 +287,8 @@ Version()
|
||||
#endif
|
||||
Msg("default escape sequence `%s%s\'", FmtCtl(DEFATTN, acA1),
|
||||
FmtCtl(DEFESC, acA2));
|
||||
Msg("default site-wide configuration in `%s'", CLIENTCONFIGFILE);
|
||||
Msg("default per-user configuration in `%s'", "$HOME/.consolerc");
|
||||
|
||||
BuildString((char *)0, acA1);
|
||||
if (optionlist[0] == (char *)0)
|
||||
@ -310,10 +309,12 @@ Version()
|
||||
BuildStringChar('0' + DMALLOC_VERSION_MINOR, acA1);
|
||||
BuildStringChar('.', acA1);
|
||||
BuildStringChar('0' + DMALLOC_VERSION_PATCH, acA1);
|
||||
#if defined(DMALLOC_VERSION_BETA)
|
||||
if (DMALLOC_VERSION_BETA != 0) {
|
||||
BuildString("-b", acA1);
|
||||
BuildStringChar('0' + DMALLOC_VERSION_BETA, acA1);
|
||||
}
|
||||
#endif
|
||||
Msg("dmalloc version: %s", acA1->string);
|
||||
#endif
|
||||
#if HAVE_OPENSSL
|
||||
@ -388,7 +389,7 @@ ValidateEsc()
|
||||
{
|
||||
unsigned char c1, c2;
|
||||
|
||||
if (!fStrip)
|
||||
if (config->striphigh != FLAGTRUE)
|
||||
return;
|
||||
|
||||
if (chAttn == -1 || chEsc == -1) {
|
||||
@ -463,7 +464,7 @@ GetPort(pcToHost, sPort)
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
if (portPath == (STRING *)0)
|
||||
portPath = AllocString();
|
||||
BuildStringPrint(portPath, "%s/%hu", pcInMaster, sPort);
|
||||
BuildStringPrint(portPath, "%s/%hu", config->master, sPort);
|
||||
port.sun_family = AF_UNIX;
|
||||
if (portPath->used > sizeof(port.sun_path)) {
|
||||
Error("GetPort: path to socket too long: %s", portPath->string);
|
||||
@ -607,7 +608,15 @@ DestroyDataStructures()
|
||||
C2Cooked();
|
||||
if (cfstdout != (CONSFILE *)0)
|
||||
FileUnopen(cfstdout);
|
||||
DestroyConfig(pConfig);
|
||||
DestroyConfig(optConf);
|
||||
DestroyConfig(config);
|
||||
DestroyTerminal(pTerm);
|
||||
if (myAddrs != (struct in_addr *)0)
|
||||
free(myAddrs);
|
||||
DestroyStrings();
|
||||
if (substData != (SUBST *) 0)
|
||||
free(substData);
|
||||
}
|
||||
|
||||
char *
|
||||
@ -944,6 +953,129 @@ DoExec(pcf)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ExpandString(char *str, CONSFILE *c)
|
||||
#else
|
||||
ExpandString(str, c)
|
||||
char *str;
|
||||
CONSFILE *c;
|
||||
#endif
|
||||
{
|
||||
char s;
|
||||
short backslash = 0;
|
||||
short cntrl = 0;
|
||||
char oct = '\000';
|
||||
short octs = 0;
|
||||
static STRING *exp = (STRING *)0;
|
||||
|
||||
if (str == (char *)0 || c == (CONSFILE *)0)
|
||||
return;
|
||||
|
||||
if (exp == (STRING *)0)
|
||||
exp = AllocString();
|
||||
|
||||
BuildString((char *)0, exp);
|
||||
|
||||
backslash = 0;
|
||||
cntrl = 0;
|
||||
while ((s = (*str++)) != '\000') {
|
||||
if (octs > 0 && octs < 3 && s >= '0' && s <= '7') {
|
||||
++octs;
|
||||
oct = oct * 8 + (s - '0');
|
||||
continue;
|
||||
}
|
||||
if (octs != 0) {
|
||||
BuildStringChar(oct, exp);
|
||||
octs = 0;
|
||||
oct = '\000';
|
||||
}
|
||||
if (backslash) {
|
||||
backslash = 0;
|
||||
if (s == 'a')
|
||||
s = '\a';
|
||||
else if (s == 'b')
|
||||
s = '\b';
|
||||
else if (s == 'f')
|
||||
s = '\f';
|
||||
else if (s == 'n')
|
||||
s = '\n';
|
||||
else if (s == 'r')
|
||||
s = '\r';
|
||||
else if (s == 't')
|
||||
s = '\t';
|
||||
else if (s == 'v')
|
||||
s = '\v';
|
||||
else if (s == '^')
|
||||
s = '^';
|
||||
else if (s >= '0' && s <= '7') {
|
||||
++octs;
|
||||
oct = oct * 8 + (s - '0');
|
||||
continue;
|
||||
}
|
||||
BuildStringChar(s, exp);
|
||||
continue;
|
||||
}
|
||||
if (cntrl) {
|
||||
cntrl = 0;
|
||||
if (s == '?')
|
||||
s = 0x7f; /* delete */
|
||||
else
|
||||
s = s & 0x1f;
|
||||
BuildStringChar(s, exp);
|
||||
continue;
|
||||
}
|
||||
if (s == '\\') {
|
||||
backslash = 1;
|
||||
continue;
|
||||
}
|
||||
if (s == '^') {
|
||||
cntrl = 1;
|
||||
continue;
|
||||
}
|
||||
BuildStringChar(s, exp);
|
||||
}
|
||||
|
||||
if (octs != 0)
|
||||
BuildStringChar(oct, exp);
|
||||
|
||||
if (backslash)
|
||||
BuildStringChar('\\', exp);
|
||||
|
||||
if (cntrl)
|
||||
BuildStringChar('^', exp);
|
||||
|
||||
if (exp->used > 1)
|
||||
FileWrite(c, FLAGFALSE, exp->string, exp->used - 1);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
PrintSubst(CONSFILE *pcf, char *pcMach, char *string, char *subst)
|
||||
#else
|
||||
PrintSubst(pcf, pcMach, string, subst)
|
||||
CONSFILE *pcf;
|
||||
char *pcMach;
|
||||
char *string;
|
||||
char *subst;
|
||||
#endif
|
||||
{
|
||||
if (string == (char *)0)
|
||||
return;
|
||||
|
||||
if (subst != (char *)0) {
|
||||
char *str;
|
||||
if ((str = StrDup(string)) == (char *)0)
|
||||
OutOfMem();
|
||||
substData->data = (void *)config;
|
||||
config->console = pcMach;
|
||||
ProcessSubst(substData, &str, (char **)0, (char *)0, subst);
|
||||
ExpandString(str, pcf);
|
||||
free(str);
|
||||
} else
|
||||
ExpandString(string, pcf);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
Interact(CONSFILE *pcf, char *pcMach)
|
||||
@ -962,8 +1094,10 @@ Interact(pcf, pcMach)
|
||||
/* 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)
|
||||
if (prevConsole != (CONSFILE *)0) {
|
||||
FileClose(&prevConsole);
|
||||
PrintSubst(cfstdout, prevName, pTerm->detach, pTerm->detachsubst);
|
||||
}
|
||||
if (prevName != (char *)0) {
|
||||
free(prevName);
|
||||
prevName = (char *)0;
|
||||
@ -976,6 +1110,8 @@ Interact(pcf, pcMach)
|
||||
FileWrite(pcf, FLAGFALSE, "\n", 1);
|
||||
}
|
||||
|
||||
PrintSubst(cfstdout, pcMach, pTerm->attach, pTerm->attachsubst);
|
||||
|
||||
C2Raw();
|
||||
|
||||
/* set socket to non-blocking */
|
||||
@ -1024,7 +1160,7 @@ Interact(pcf, pcMach)
|
||||
FilePrint(pcf, FLAGFALSE, "%c%c", OB_IAC, OB_ABRT);
|
||||
FileSetQuoteIAC(pcf, FLAGTRUE);
|
||||
} else {
|
||||
if (fStrip) {
|
||||
if (config->striphigh == FLAGTRUE) {
|
||||
for (i = 0; i < nc; ++i)
|
||||
acMesg[i] &= 127;
|
||||
}
|
||||
@ -1091,7 +1227,7 @@ Interact(pcf, pcMach)
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (fStrip) {
|
||||
if (config->striphigh == FLAGTRUE) {
|
||||
for (i = 0; i < l; ++i)
|
||||
acMesg[i] &= 127;
|
||||
}
|
||||
@ -1123,7 +1259,7 @@ Interact(pcf, pcMach)
|
||||
}
|
||||
}
|
||||
if (execCmdFile == (CONSFILE *)0) {
|
||||
if (fStrip) {
|
||||
if (config->striphigh == FLAGTRUE) {
|
||||
for (i = 0; i < nc; ++i)
|
||||
acMesg[i] &= 127;
|
||||
}
|
||||
@ -1154,7 +1290,11 @@ Interact(pcf, pcMach)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
C2Cooked();
|
||||
|
||||
PrintSubst(cfstdout, pcMach, pTerm->detach, pTerm->detachsubst);
|
||||
|
||||
if (fVerbose)
|
||||
printf("Console %s closed.\n", pcMach);
|
||||
}
|
||||
@ -1386,7 +1526,7 @@ DoCmds(master, pports, cmdi)
|
||||
continue;
|
||||
}
|
||||
#if HAVE_OPENSSL
|
||||
if (fReqEncryption) {
|
||||
if (config->sslenabled == FLAGTRUE) {
|
||||
FileWrite(pcf, FLAGFALSE, "ssl\r\n", 5);
|
||||
t = ReadReply(pcf, 0);
|
||||
if (strcmp(t, "ok\r\n") == 0) {
|
||||
@ -1397,7 +1537,7 @@ DoCmds(master, pports, cmdi)
|
||||
FileClose(&pcf);
|
||||
continue;
|
||||
}
|
||||
} else if (fAllowUnencrypted == 0) {
|
||||
} else if (config->sslrequired == FLAGTRUE) {
|
||||
Error("Encryption not supported by server `%s'",
|
||||
serverName);
|
||||
FileClose(&pcf);
|
||||
@ -1406,7 +1546,7 @@ DoCmds(master, pports, cmdi)
|
||||
}
|
||||
#endif
|
||||
|
||||
FilePrint(pcf, FLAGFALSE, "login %s\r\n", pcUser);
|
||||
FilePrint(pcf, FLAGFALSE, "login %s\r\n", config->username);
|
||||
|
||||
t = ReadReply(pcf, 0);
|
||||
if (strncmp(t, "passwd?", 7) == 0) {
|
||||
@ -1425,7 +1565,7 @@ DoCmds(master, pports, cmdi)
|
||||
if (tmpString->used <= 1) {
|
||||
char *pass;
|
||||
BuildStringPrint(tmpString, "Enter %s@%s's password: ",
|
||||
pcUser, hostname);
|
||||
config->username, hostname);
|
||||
pass = GetPassword(tmpString->string);
|
||||
if (pass == (char *)0) {
|
||||
Error("could not get password from tty for `%s'",
|
||||
@ -1590,13 +1730,15 @@ main(argc, argv)
|
||||
int opt;
|
||||
int fLocal;
|
||||
static STRING *acPorts = (STRING *)0;
|
||||
static char acOpts[] = "7aAb:B:c:d:De:EfFhiIl:M:p:PqQrRsSt:uUvVwWx";
|
||||
static char acOpts[] = "7aAb:B:c:C:d:De:EfFhiIl:M:np:PqQrRsSt:uUvVwWx";
|
||||
extern int optind;
|
||||
extern int optopt;
|
||||
extern char *optarg;
|
||||
static STRING *textMsg = (STRING *)0;
|
||||
int cmdi;
|
||||
static STRING *consoleName = (STRING *)0;
|
||||
short readSystemConf = 1;
|
||||
char *userConf = (char *)0;
|
||||
|
||||
isMultiProc = 0; /* make sure stuff DOESN'T have the pid */
|
||||
|
||||
@ -1613,6 +1755,17 @@ main(argc, argv)
|
||||
++progname;
|
||||
}
|
||||
|
||||
/* prep the config options */
|
||||
if ((optConf = (CONFIG *)calloc(1, sizeof(CONFIG))) == (CONFIG *)0)
|
||||
OutOfMem();
|
||||
if ((config = (CONFIG *)calloc(1, sizeof(CONFIG))) == (CONFIG *)0)
|
||||
OutOfMem();
|
||||
if ((pConfig = (CONFIG *)calloc(1, sizeof(CONFIG))) == (CONFIG *)0)
|
||||
OutOfMem();
|
||||
/* and the terminal options */
|
||||
if ((pTerm = (TERM *)calloc(1, sizeof(TERM))) == (TERM *)0)
|
||||
OutOfMem();
|
||||
|
||||
/* command line parsing
|
||||
*/
|
||||
pcCmd = (char *)0;
|
||||
@ -1620,7 +1773,7 @@ main(argc, argv)
|
||||
while ((opt = getopt(argc, argv, acOpts)) != EOF) {
|
||||
switch (opt) {
|
||||
case '7': /* strip high-bit */
|
||||
fStrip = 1;
|
||||
optConf->striphigh = FLAGTRUE;
|
||||
break;
|
||||
|
||||
case 'A': /* attach with log replay */
|
||||
@ -1641,9 +1794,15 @@ main(argc, argv)
|
||||
OutOfMem();
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
userConf = optarg;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
#if HAVE_OPENSSL
|
||||
pcCredFile = optarg;
|
||||
if ((optConf->sslcredentials =
|
||||
StrDup(optarg)) == (char *)0)
|
||||
OutOfMem();
|
||||
#endif
|
||||
break;
|
||||
|
||||
@ -1661,12 +1820,13 @@ main(argc, argv)
|
||||
|
||||
case 'E':
|
||||
#if HAVE_OPENSSL
|
||||
fReqEncryption = 0;
|
||||
optConf->sslenabled = FLAGFALSE;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'e': /* set escape chars */
|
||||
ParseEsc(optarg);
|
||||
if ((optConf->escape = StrDup(optarg)) == (char *)0)
|
||||
OutOfMem();
|
||||
break;
|
||||
|
||||
case 'F': /* force attach with log replay */
|
||||
@ -1684,15 +1844,22 @@ main(argc, argv)
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
pcUser = optarg;
|
||||
if ((optConf->username = StrDup(optarg)) == (char *)0)
|
||||
OutOfMem();
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
pcInMaster = optarg;
|
||||
if ((optConf->master = StrDup(optarg)) == (char *)0)
|
||||
OutOfMem();
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
readSystemConf = 0;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
pcPort = optarg;
|
||||
if ((optConf->port = StrDup(optarg)) == (char *)0)
|
||||
OutOfMem();
|
||||
break;
|
||||
|
||||
case 'P': /* send a pid command to the server */
|
||||
@ -1737,7 +1904,7 @@ main(argc, argv)
|
||||
|
||||
case 'U':
|
||||
#if HAVE_OPENSSL
|
||||
fAllowUnencrypted = 1;
|
||||
optConf->sslrequired = FLAGFALSE;
|
||||
#endif
|
||||
break;
|
||||
|
||||
@ -1783,6 +1950,109 @@ main(argc, argv)
|
||||
Bye(EX_OK);
|
||||
}
|
||||
|
||||
ProbeInterfaces(INADDR_ANY);
|
||||
|
||||
if (readSystemConf)
|
||||
ReadConf(CLIENTCONFIGFILE, FLAGFALSE);
|
||||
|
||||
if (userConf == (char *)0) {
|
||||
/* read the config files */
|
||||
char *h = (char *)0;
|
||||
|
||||
if (((h = getenv("HOME")) == (char *)0) &&
|
||||
((pwdMe = getpwuid(getuid())) == (struct passwd *)0)) {
|
||||
Error("$HOME does not exist and getpwuid fails: %d: %s",
|
||||
(int)(getuid()), strerror(errno));
|
||||
} else {
|
||||
if (h == (char *)0) {
|
||||
if (pwdMe->pw_dir == (char *)0 ||
|
||||
pwdMe->pw_dir[0] == '\000') {
|
||||
Error("Home directory for uid %d is not defined",
|
||||
(int)(getuid()));
|
||||
Bye(EX_UNAVAILABLE);
|
||||
} else {
|
||||
h = pwdMe->pw_dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (h != (char *)0) {
|
||||
BuildTmpString((char *)0);
|
||||
BuildTmpString(h);
|
||||
h = BuildTmpString("/.consolerc");
|
||||
ReadConf(h, FLAGFALSE);
|
||||
BuildTmpString((char *)0);
|
||||
}
|
||||
} else
|
||||
ReadConf(userConf, FLAGTRUE);
|
||||
|
||||
if (optConf->striphigh != FLAGUNKNOWN)
|
||||
config->striphigh = optConf->striphigh;
|
||||
else if (pConfig->striphigh != FLAGUNKNOWN)
|
||||
config->striphigh = pConfig->striphigh;
|
||||
else
|
||||
config->striphigh = FLAGFALSE;
|
||||
|
||||
if (optConf->escape != (char *)0)
|
||||
ParseEsc(optConf->escape);
|
||||
else if (pConfig->escape != (char *)0)
|
||||
ParseEsc(pConfig->escape);
|
||||
|
||||
if (optConf->username != (char *)0)
|
||||
config->username = StrDup(optConf->username);
|
||||
else if (pConfig->username != (char *)0)
|
||||
config->username = StrDup(pConfig->username);
|
||||
else
|
||||
config->username = (char *)0;
|
||||
|
||||
if (optConf->master != (char *)0 && optConf->master[0] != '\000')
|
||||
config->master = StrDup(optConf->master);
|
||||
else if (pConfig->master != (char *)0 && pConfig->master[0] != '\000')
|
||||
config->master = StrDup(pConfig->master);
|
||||
else
|
||||
config->master = StrDup(
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
UDSDIR
|
||||
#else
|
||||
MASTERHOST /* which machine is current */
|
||||
#endif
|
||||
);
|
||||
if (config->master == (char *)0)
|
||||
OutOfMem();
|
||||
|
||||
if (optConf->port != (char *)0 && optConf->port[0] != '\000')
|
||||
config->port = StrDup(optConf->port);
|
||||
else if (pConfig->port != (char *)0 && pConfig->port[0] != '\000')
|
||||
config->port = StrDup(pConfig->port);
|
||||
else
|
||||
config->port = StrDup(DEFPORT);
|
||||
if (config->port == (char *)0)
|
||||
OutOfMem();
|
||||
|
||||
#if HAVE_OPENSSL
|
||||
if (optConf->sslcredentials != (char *)0 &&
|
||||
optConf->sslcredentials[0] != '\000')
|
||||
config->sslcredentials = StrDup(optConf->sslcredentials);
|
||||
else if (pConfig->sslcredentials != (char *)0 &&
|
||||
pConfig->sslcredentials[0] != '\000')
|
||||
config->sslcredentials = StrDup(pConfig->sslcredentials);
|
||||
else
|
||||
config->sslcredentials = (char *)0;
|
||||
|
||||
if (optConf->sslenabled != FLAGUNKNOWN)
|
||||
config->sslenabled = optConf->sslenabled;
|
||||
else if (pConfig->sslenabled != FLAGUNKNOWN)
|
||||
config->sslenabled = pConfig->sslenabled;
|
||||
else
|
||||
config->sslenabled = FLAGTRUE;
|
||||
|
||||
if (optConf->sslrequired != FLAGUNKNOWN)
|
||||
config->sslrequired = optConf->sslrequired;
|
||||
else if (pConfig->sslrequired != FLAGUNKNOWN)
|
||||
config->sslrequired = pConfig->sslrequired;
|
||||
else
|
||||
config->sslrequired = FLAGTRUE;
|
||||
#endif
|
||||
|
||||
/* finish resolving the command to do */
|
||||
if (pcCmd == (char *)0) {
|
||||
pcCmd = "attach";
|
||||
@ -1813,23 +2083,20 @@ main(argc, argv)
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
#if !USE_UNIX_DOMAIN_SOCKETS
|
||||
/* if we somehow lost the port (or got an empty string), reset */
|
||||
if (pcPort == (char *)0 || pcPort[0] == '\000')
|
||||
pcPort = DEFPORT;
|
||||
|
||||
/* Look for non-numeric characters */
|
||||
for (opt = 0; pcPort[opt] != '\000'; opt++)
|
||||
if (!isdigit((int)pcPort[opt]))
|
||||
for (opt = 0; config->port[opt] != '\000'; opt++)
|
||||
if (!isdigit((int)config->port[opt]))
|
||||
break;
|
||||
|
||||
if (pcPort[opt] == '\000') {
|
||||
if (config->port[opt] == '\000') {
|
||||
/* numeric only */
|
||||
bindPort = atoi(pcPort);
|
||||
bindPort = atoi(config->port);
|
||||
} else {
|
||||
/* non-numeric only */
|
||||
struct servent *pSE;
|
||||
if ((pSE = getservbyname(pcPort, "tcp")) == (struct servent *)0) {
|
||||
Error("getservbyname(%s) failed", pcPort);
|
||||
if ((pSE =
|
||||
getservbyname(config->port, "tcp")) == (struct servent *)0) {
|
||||
Error("getservbyname(%s) failed", config->port);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
} else {
|
||||
bindPort = ntohs((u_short) pSE->s_port);
|
||||
@ -1837,24 +2104,28 @@ main(argc, argv)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pcUser == (char *)0 || pcUser[0] == '\000') {
|
||||
if (((pcUser = getenv("LOGNAME")) == (char *)0) &&
|
||||
((pcUser = getenv("USER")) == (char *)0) &&
|
||||
if (config->username == (char *)0 || config->username[0] == '\000') {
|
||||
if (config->username != (char *)0)
|
||||
free(config->username);
|
||||
if (((config->username = getenv("LOGNAME")) == (char *)0) &&
|
||||
((config->username = getenv("USER")) == (char *)0) &&
|
||||
((pwdMe = getpwuid(getuid())) == (struct passwd *)0)) {
|
||||
Error
|
||||
("$LOGNAME and $USER do not exist and getpwuid fails: %d: %s",
|
||||
(int)(getuid()), strerror(errno));
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
if (pcUser == (char *)0) {
|
||||
if (config->username == (char *)0) {
|
||||
if (pwdMe->pw_name == (char *)0 || pwdMe->pw_name[0] == '\000') {
|
||||
Error("Username for uid %d does not exist",
|
||||
(int)(getuid()));
|
||||
Bye(EX_UNAVAILABLE);
|
||||
} else {
|
||||
pcUser = pwdMe->pw_name;
|
||||
config->username = pwdMe->pw_name;
|
||||
}
|
||||
}
|
||||
if ((config->username = StrDup(config->username)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
|
||||
if (execCmd == (STRING *)0)
|
||||
@ -1866,7 +2137,7 @@ main(argc, argv)
|
||||
|
||||
BuildString((char *)0, acPorts);
|
||||
BuildStringChar('@', acPorts);
|
||||
BuildString(pcInMaster, acPorts);
|
||||
BuildString(config->master, acPorts);
|
||||
|
||||
#if HAVE_OPENSSL
|
||||
SetupSSL(); /* should only do if we want ssl - provide flag! */
|
||||
@ -1890,7 +2161,7 @@ main(argc, argv)
|
||||
|
||||
for (;;) {
|
||||
if (gotoConsole == (CONSFILE *)0)
|
||||
DoCmds(pcInMaster, acPorts->string, cmdi);
|
||||
DoCmds(config->master, acPorts->string, cmdi);
|
||||
else
|
||||
Interact(gotoConsole, gotoName);
|
||||
|
||||
|
@ -1,15 +1,17 @@
|
||||
.\" $Id: console.man,v 1.48 2004/04/20 01:30:13 bryan Exp $
|
||||
.TH CONSOLE 1 "2004/04/20" "conserver-8.1.5" "conserver"
|
||||
.\" $Id: console.man,v 1.51 2004/05/25 00:38:15 bryan Exp $
|
||||
.TH CONSOLE 1 "2004/05/25" "conserver-8.1.6" "conserver"
|
||||
.SH NAME
|
||||
console \- console server client program
|
||||
.SH SYNOPSIS
|
||||
.B console
|
||||
.RB [ \-aAfFsS ]
|
||||
.RB [ \-7DEUv ]
|
||||
.RB [ \-7DEnUv ]
|
||||
.RB [ \-c
|
||||
.IR cred ]
|
||||
.RB [ \-C
|
||||
.IR config ]
|
||||
.BR [ \-M
|
||||
.IR mach ]
|
||||
.IR master ]
|
||||
.BR [ \-p
|
||||
.IR port ]
|
||||
.BR [ \-e
|
||||
@ -20,11 +22,13 @@ console \- console server client program
|
||||
.br
|
||||
.B console
|
||||
.RB [ \-hiIPrRuVwWx ]
|
||||
.RB [ \-7DEUv ]
|
||||
.RB [ \-7DEnUv ]
|
||||
.RB [ \-c
|
||||
.IR cred ]
|
||||
.RB [ \-C
|
||||
.IR config ]
|
||||
.RB [ \-M
|
||||
.IR mach ]
|
||||
.IR master ]
|
||||
.RB [ \-p
|
||||
.IR port ]
|
||||
.RB [ \-d
|
||||
@ -37,11 +41,13 @@ console \- console server client program
|
||||
.br
|
||||
.B console
|
||||
.RB [ \-qQ ]
|
||||
.RB [ \-7DEUv ]
|
||||
.RB [ \-7DEnUv ]
|
||||
.RB [ \-c
|
||||
.IR cred ]
|
||||
.RB [ \-C
|
||||
.IR config ]
|
||||
.RB [ \-M
|
||||
.IR mach ]
|
||||
.IR master ]
|
||||
.RB [ \-p
|
||||
.IR port ]
|
||||
.SH DESCRIPTION
|
||||
@ -120,6 +126,10 @@ to users on the primary server.
|
||||
Load an SSL certificate and key from the PEM encoded file
|
||||
.IR cred .
|
||||
.TP
|
||||
.BI \-C config
|
||||
Use the per-user configuration file
|
||||
.IR conf .
|
||||
.TP
|
||||
.B \-d
|
||||
Disconnect the users specified by
|
||||
.IR user @ console .
|
||||
@ -187,19 +197,34 @@ uses $USER if its uid matches the user's real uid,
|
||||
or $LOGNAME if its uid matches the user's real uid,
|
||||
or else the name associated with the user's real uid.
|
||||
.TP
|
||||
.BI \-M mach
|
||||
.BI \-M master
|
||||
The
|
||||
.B console
|
||||
client program polls
|
||||
.I mach
|
||||
.I master
|
||||
as the primary server,
|
||||
rather than the default set at compile time (typically
|
||||
.RB `` console '').
|
||||
The default
|
||||
.I mach
|
||||
.I master
|
||||
may be changed at compile time using the
|
||||
.B --with-master
|
||||
option.
|
||||
If
|
||||
.B --with-uds
|
||||
is used to enable Unix domain sockets, however, this option points
|
||||
.B console
|
||||
to the directory which holds those sockets.
|
||||
The default
|
||||
.I master
|
||||
directory
|
||||
.RB (`` /tmp/conserver '')
|
||||
may be changed at compile time using the
|
||||
.B --with-uds
|
||||
option.
|
||||
.TP
|
||||
.BI \-n
|
||||
Do not read the system-wide configuration file.
|
||||
.TP
|
||||
.BI \-p port
|
||||
Set the port to connect to.
|
||||
@ -211,6 +236,9 @@ may be changed at compile time
|
||||
using the
|
||||
.B --with-port
|
||||
option.
|
||||
If the
|
||||
.B --with-uds
|
||||
option was used, this option is ignored.
|
||||
.TP
|
||||
.B \-P
|
||||
Display the pid of the master daemon process on each server.
|
||||
@ -395,6 +423,311 @@ The idletimeout configuration option for the console.
|
||||
.TP
|
||||
.I idlestring
|
||||
The idlestring configuration option for the console.
|
||||
.SH CONFIGURATION
|
||||
.B Console
|
||||
reads configuration information from the system-wide configuration file
|
||||
.RB ( console.cf ),
|
||||
then the per-user configuration file
|
||||
.RB ( .consolerc ),
|
||||
and then applies command-line arguments.
|
||||
Each configuration location can override the previous.
|
||||
The same happens when parsing an individual file - the later entries
|
||||
always override the earlier entries.
|
||||
Because of that, you should put ``global'' defaults first and
|
||||
more specific defaults second.
|
||||
.PP
|
||||
The configuration file is read using the same parser as
|
||||
.BR conserver.cf (5),
|
||||
and you should check that manpage for parser details.
|
||||
.B Console
|
||||
recognizes the following configuration blocks.
|
||||
.TP 8
|
||||
.B config
|
||||
.RI [ " hostname " | " ipaddr " ]
|
||||
.br
|
||||
Define a configuration block for the host named
|
||||
.I hostname
|
||||
or using the address
|
||||
.IR ipaddr .
|
||||
If the value of ``*'' is used, the configuration block will be applied to
|
||||
all hosts.
|
||||
.RS
|
||||
.TP 15
|
||||
.B escape
|
||||
.I esc
|
||||
.br
|
||||
Set the escape sequence (see the
|
||||
.B \-e
|
||||
command-line flag).
|
||||
.TP
|
||||
.B master
|
||||
.I master
|
||||
.br
|
||||
Set the default master to
|
||||
.I master
|
||||
(see the
|
||||
.B \-M
|
||||
command-line flag).
|
||||
.TP
|
||||
.B port
|
||||
.I port
|
||||
.br
|
||||
Set the default port to
|
||||
.I port
|
||||
(see the
|
||||
.B \-p
|
||||
command-line flag).
|
||||
.TP
|
||||
.B sslcredentials
|
||||
.I filename
|
||||
.br
|
||||
Set the
|
||||
.SM SSL
|
||||
credentials file location (see the
|
||||
.B \-c
|
||||
command-line flag).
|
||||
.TP
|
||||
.B sslenabled
|
||||
.RB [ " yes " | " true "
|
||||
.RB | " on " | " no "
|
||||
.RB | " false " | " off " ]
|
||||
.br
|
||||
Set whether or not encryption is attempted when talking to servers (see the
|
||||
.B \-E
|
||||
command-line flag).
|
||||
.TP
|
||||
.B sslrequired
|
||||
.RB [ " yes " | " true "
|
||||
.RB | " on " | " no "
|
||||
.RB | " false " | " off " ]
|
||||
.br
|
||||
Set whether or not encryption is required when talking to servers (see the
|
||||
.B \-U
|
||||
command-line flag).
|
||||
.TP
|
||||
.B striphigh
|
||||
.RB [ " yes " | " true "
|
||||
.RB | " on " | " no "
|
||||
.RB | " false " | " off " ]
|
||||
.br
|
||||
Set whether or not to strip the high bit off all data received
|
||||
(see the
|
||||
.B \-7
|
||||
command-line flag).
|
||||
.TP
|
||||
.B username
|
||||
.I user
|
||||
.br
|
||||
Set the username passed to the server to
|
||||
.I user
|
||||
(see the
|
||||
.B \-l
|
||||
command-line flag).
|
||||
.RE
|
||||
.TP 8
|
||||
.B terminal
|
||||
.I type
|
||||
.br
|
||||
Define a configuration block when using a terminal of type
|
||||
.IR type .
|
||||
If the value of ``*'' is used, the configuration block will be applied to
|
||||
all terminal types.
|
||||
.RS
|
||||
.TP 15
|
||||
.B attach
|
||||
.RI [ " string "
|
||||
| "" ]
|
||||
.br
|
||||
Set a
|
||||
.I string
|
||||
to print when successfully attached to a console.
|
||||
Character substitions will be performed based on the
|
||||
.B attachsubst
|
||||
value and occur
|
||||
.I before
|
||||
interpretation of the special characters below.
|
||||
If the null string (``""'') is used, no string will be printed.
|
||||
.I string
|
||||
is a simple character string with the exception of `\e'
|
||||
and `^':
|
||||
.RS
|
||||
.RS
|
||||
.sp
|
||||
.PD 0
|
||||
.TP 6
|
||||
.B \ea
|
||||
alert
|
||||
.TP
|
||||
.B \eb
|
||||
backspace
|
||||
.TP
|
||||
.B \ef
|
||||
form-feed
|
||||
.TP
|
||||
.B \en
|
||||
newline
|
||||
.TP
|
||||
.B \er
|
||||
carriage-return
|
||||
.TP
|
||||
.B \et
|
||||
tab
|
||||
.TP
|
||||
.B \ev
|
||||
vertical-tab
|
||||
.TP
|
||||
.B \e\e
|
||||
backslash
|
||||
.TP
|
||||
.B \e^
|
||||
circumflex
|
||||
.TP
|
||||
.BI \e ooo
|
||||
octal representation of a character (where
|
||||
.I ooo
|
||||
is one to three octal digits)
|
||||
.TP
|
||||
.BI \e c
|
||||
character
|
||||
.I c
|
||||
.TP
|
||||
.B ^?
|
||||
delete
|
||||
.TP
|
||||
.BI ^ c
|
||||
control character
|
||||
.RI ( c
|
||||
is ``and''ed with 0x1f)
|
||||
.PD
|
||||
.RE
|
||||
.RE
|
||||
.IP
|
||||
An interesting use of
|
||||
.B attach
|
||||
and
|
||||
.B attachsubst
|
||||
would be:
|
||||
.RS
|
||||
.IP
|
||||
.ft CR
|
||||
.nf
|
||||
terminal xterm {
|
||||
attach "^[]0;conserver: U@C^G";
|
||||
attachsubst U=us,C=cs;
|
||||
}
|
||||
.fi
|
||||
.ft
|
||||
.RE
|
||||
.TP
|
||||
.B attachsubst
|
||||
[\f2c\fP=\f2t\fP[\f2n\fP]\f2f\fP[,...]
|
||||
| "" ]
|
||||
.br
|
||||
Perform character substitutions on the
|
||||
.B attach
|
||||
value.
|
||||
A series of replacements can be defined by specifying a
|
||||
comma-separated list of
|
||||
\f2c\fP=\f2t\fP[\f2n\fP]\f2f\fP
|
||||
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 u
|
||||
username
|
||||
.TP
|
||||
.B c
|
||||
console name
|
||||
.sp
|
||||
.PP
|
||||
Numeric Replacement
|
||||
.TP
|
||||
none available (yet)
|
||||
.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', `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 15
|
||||
.B detach
|
||||
.RI [ " string "
|
||||
| "" ]
|
||||
.br
|
||||
Set a
|
||||
.I string
|
||||
to print once detached from a console.
|
||||
Character substitions will be performed based on the
|
||||
.B detachsubst
|
||||
value.
|
||||
See the
|
||||
.B attach
|
||||
option for an explanation of
|
||||
.IR string .
|
||||
If the null string (``""'') is used, no string will be printed.
|
||||
.TP
|
||||
.B detachsubst
|
||||
[\f2c\fP=\f2t\fP[\f2n\fP]\f2f\fP[,...]
|
||||
| "" ]
|
||||
.br
|
||||
Perform character substitutions on the
|
||||
.B detach
|
||||
value.
|
||||
See the
|
||||
.B attachsubst
|
||||
option for an explanation of the format string.
|
||||
.RE
|
||||
.PP
|
||||
A simple configuration to set a new default escape sequence and override
|
||||
the master location would be:
|
||||
.IP
|
||||
.ft CR
|
||||
.nf
|
||||
# override options for all hosts
|
||||
config * {
|
||||
master localhost;
|
||||
escape ^Ee;
|
||||
}
|
||||
# set things more specific to host1
|
||||
# note: if the entries were reversed, host1
|
||||
# would also use localhost.
|
||||
config host1 {
|
||||
master console1;
|
||||
}
|
||||
.fi
|
||||
.ft
|
||||
.SH "ESCAPE SEQUENCES"
|
||||
The connection can be controlled by a two-character escape sequence, followed
|
||||
by a command.
|
||||
@ -574,6 +907,22 @@ or number of days is displayed.
|
||||
console \-e "^[1" lv426
|
||||
Requests a connection to the host ``lv426'' with the escape characters
|
||||
set to ``escape one''.
|
||||
.SH FILES
|
||||
.PP
|
||||
The following default file locations may be overridden
|
||||
at compile time or by the command-line options described above.
|
||||
Run
|
||||
.B console \-V
|
||||
to see the defaults set at compile time.
|
||||
.PP
|
||||
.PD 0
|
||||
.TP 25
|
||||
.B /etc/console.cf
|
||||
system-wide configuration file
|
||||
.TP
|
||||
.B $HOME/.consolerc
|
||||
per-user configuration file
|
||||
.PD
|
||||
.SH BUGS
|
||||
It is possible to create a loop of console connections, with ugly results.
|
||||
Never run
|
||||
|
720
console/readconf.c
Normal file
720
console/readconf.c
Normal file
@ -0,0 +1,720 @@
|
||||
/*
|
||||
* $Id: readconf.c,v 5.2 2004/05/25 00:38:15 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
* Maintainer/Enhancer: Bryan Stansell (bryan@conserver.com)
|
||||
*/
|
||||
|
||||
#include <compat.h>
|
||||
|
||||
#include <cutil.h>
|
||||
#include <readconf.h>
|
||||
|
||||
CONFIG *parserConfigTemp = (CONFIG *)0;
|
||||
CONFIG *parserConfigDefault = (CONFIG *)0;
|
||||
CONFIG *pConfig = (CONFIG *)0;
|
||||
TERM *parserTermTemp = (TERM *)0;
|
||||
TERM *parserTermDefault = (TERM *)0;
|
||||
TERM *pTerm = (TERM *)0;
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
DestroyConfig(CONFIG *c)
|
||||
#else
|
||||
DestroyConfig(c)
|
||||
CONFIG *c;
|
||||
#endif
|
||||
{
|
||||
if (c == (CONFIG *)0)
|
||||
return;
|
||||
if (c->username != (char *)0)
|
||||
free(c->username);
|
||||
if (c->master != (char *)0)
|
||||
free(c->master);
|
||||
if (c->port != (char *)0)
|
||||
free(c->port);
|
||||
if (c->escape != (char *)0)
|
||||
free(c->escape);
|
||||
#if HAVE_OPENSSL
|
||||
if (c->sslcredentials != (char *)0)
|
||||
free(c->sslcredentials);
|
||||
#endif
|
||||
free(c);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ApplyConfigDefault(CONFIG *c)
|
||||
#else
|
||||
ApplyConfigDefault(c)
|
||||
CONFIG *c;
|
||||
#endif
|
||||
{
|
||||
if (parserConfigDefault == (CONFIG *)0)
|
||||
return;
|
||||
|
||||
if (parserConfigDefault->username != (char *)0) {
|
||||
if (c->username != (char *)0)
|
||||
free(c->username);
|
||||
if ((c->username =
|
||||
StrDup(parserConfigDefault->username)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
if (parserConfigDefault->master != (char *)0) {
|
||||
if (c->master != (char *)0)
|
||||
free(c->master);
|
||||
if ((c->master = StrDup(parserConfigDefault->master)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
if (parserConfigDefault->port != (char *)0) {
|
||||
if (c->port != (char *)0)
|
||||
free(c->port);
|
||||
if ((c->port = StrDup(parserConfigDefault->port)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
if (parserConfigDefault->escape != (char *)0) {
|
||||
if (c->escape != (char *)0)
|
||||
free(c->escape);
|
||||
if ((c->escape = StrDup(parserConfigDefault->escape)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
if (parserConfigDefault->striphigh != FLAGUNKNOWN)
|
||||
c->striphigh = parserConfigDefault->striphigh;
|
||||
#if HAVE_OPENSSL
|
||||
if (parserConfigDefault->sslcredentials != (char *)0) {
|
||||
if (c->sslcredentials != (char *)0)
|
||||
free(c->sslcredentials);
|
||||
if ((c->sslcredentials =
|
||||
StrDup(parserConfigDefault->sslcredentials)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
if (parserConfigDefault->sslrequired != FLAGUNKNOWN)
|
||||
c->sslrequired = parserConfigDefault->sslrequired;
|
||||
if (parserConfigDefault->sslenabled != FLAGUNKNOWN)
|
||||
c->sslenabled = parserConfigDefault->sslenabled;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ConfigBegin(char *id)
|
||||
#else
|
||||
ConfigBegin(id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "ConfigBegin(%s) [%s:%d]", id, file, line));
|
||||
if (id == (char *)0 || id[0] == '\000') {
|
||||
Error("empty config name [%s:%d]", file, line);
|
||||
return;
|
||||
}
|
||||
if (parserConfigTemp != (CONFIG *)0)
|
||||
DestroyConfig(parserConfigTemp);
|
||||
if ((parserConfigTemp = (CONFIG *)calloc(1, sizeof(CONFIG)))
|
||||
== (CONFIG *)0)
|
||||
OutOfMem();
|
||||
ApplyConfigDefault(parserConfigTemp);
|
||||
parserConfigTemp->name = AllocString();
|
||||
BuildString(id, parserConfigTemp->name);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ConfigEnd(void)
|
||||
#else
|
||||
ConfigEnd()
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "ConfigEnd() [%s:%d]", file, line));
|
||||
|
||||
if (parserConfigTemp == (CONFIG *)0)
|
||||
return;
|
||||
|
||||
if (parserConfigTemp->name->used > 1) {
|
||||
if ((parserConfigTemp->name->string[0] == '*' &&
|
||||
parserConfigTemp->name->string[1] == '\000') ||
|
||||
IsMe(parserConfigTemp->name->string)) {
|
||||
DestroyConfig(parserConfigDefault);
|
||||
parserConfigDefault = parserConfigTemp;
|
||||
parserConfigTemp = (CONFIG *)0;
|
||||
}
|
||||
}
|
||||
|
||||
DestroyConfig(parserConfigTemp);
|
||||
parserConfigTemp = (CONFIG *)0;
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ConfigAbort(void)
|
||||
#else
|
||||
ConfigAbort()
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "ConfigAbort() [%s:%d]", file, line));
|
||||
if (parserConfigTemp == (CONFIG *)0)
|
||||
return;
|
||||
|
||||
DestroyConfig(parserConfigTemp);
|
||||
parserConfigTemp = (CONFIG *)0;
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ConfigDestroy(void)
|
||||
#else
|
||||
ConfigDestroy()
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "ConfigDestroy() [%s:%d]", file, line));
|
||||
|
||||
if (parserConfigTemp != (CONFIG *)0) {
|
||||
DestroyConfig(parserConfigTemp);
|
||||
parserConfigTemp = (CONFIG *)0;
|
||||
}
|
||||
|
||||
if (parserConfigDefault != (CONFIG *)0) {
|
||||
DestroyConfig(pConfig);
|
||||
pConfig = parserConfigDefault;
|
||||
parserConfigDefault = (CONFIG *)0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
DestroyTerminal(TERM *t)
|
||||
#else
|
||||
DestroyTerminal(t)
|
||||
TERM *t;
|
||||
#endif
|
||||
{
|
||||
if (t == (TERM *)0)
|
||||
return;
|
||||
if (t->attach != (char *)0)
|
||||
free(t->attach);
|
||||
if (t->attachsubst != (char *)0)
|
||||
free(t->attachsubst);
|
||||
if (t->detach != (char *)0)
|
||||
free(t->detach);
|
||||
if (t->detachsubst != (char *)0)
|
||||
free(t->detachsubst);
|
||||
free(t);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ApplyTermDefault(TERM *t)
|
||||
#else
|
||||
ApplyTermDefault(t)
|
||||
TERM *t;
|
||||
#endif
|
||||
{
|
||||
if (parserTermDefault == (TERM *)0)
|
||||
return;
|
||||
|
||||
if (parserTermDefault->attach != (char *)0) {
|
||||
if (t->attach != (char *)0)
|
||||
free(t->attach);
|
||||
if ((t->attach = StrDup(parserTermDefault->attach)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
if (parserTermDefault->attachsubst != (char *)0) {
|
||||
if (t->attachsubst != (char *)0)
|
||||
free(t->attachsubst);
|
||||
if ((t->attachsubst =
|
||||
StrDup(parserTermDefault->attachsubst)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
if (parserTermDefault->detach != (char *)0) {
|
||||
if (t->detach != (char *)0)
|
||||
free(t->detach);
|
||||
if ((t->detach = StrDup(parserTermDefault->detach)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
if (parserTermDefault->detachsubst != (char *)0) {
|
||||
if (t->detachsubst != (char *)0)
|
||||
free(t->detachsubst);
|
||||
if ((t->detachsubst =
|
||||
StrDup(parserTermDefault->detachsubst)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
TerminalBegin(char *id)
|
||||
#else
|
||||
TerminalBegin(id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "TerminalBegin(%s) [%s:%d]", id, file, line));
|
||||
if (id == (char *)0 || id[0] == '\000') {
|
||||
Error("empty terminal name [%s:%d]", file, line);
|
||||
return;
|
||||
}
|
||||
if (parserTermTemp != (TERM *)0)
|
||||
DestroyTerminal(parserTermTemp);
|
||||
if ((parserTermTemp = (TERM *)calloc(1, sizeof(TERM)))
|
||||
== (TERM *)0)
|
||||
OutOfMem();
|
||||
ApplyTermDefault(parserTermTemp);
|
||||
parserTermTemp->name = AllocString();
|
||||
BuildString(id, parserTermTemp->name);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
TerminalEnd(void)
|
||||
#else
|
||||
TerminalEnd()
|
||||
#endif
|
||||
{
|
||||
static char *term = (char *)0;
|
||||
|
||||
CONDDEBUG((1, "TerminalEnd() [%s:%d]", file, line));
|
||||
|
||||
if (parserTermTemp == (TERM *)0)
|
||||
return;
|
||||
|
||||
if (term == (char *)0) {
|
||||
if ((term = getenv("TERM")) == (char *)0) {
|
||||
term = "";
|
||||
}
|
||||
}
|
||||
|
||||
if (parserTermTemp->name->used > 1) {
|
||||
if ((parserTermTemp->name->string[0] == '*' &&
|
||||
parserTermTemp->name->string[1] == '\000') ||
|
||||
strcmp(parserTermTemp->name->string, term) == 0) {
|
||||
DestroyTerminal(parserTermDefault);
|
||||
parserTermDefault = parserTermTemp;
|
||||
parserTermTemp = (TERM *)0;
|
||||
}
|
||||
}
|
||||
|
||||
DestroyTerminal(parserTermTemp);
|
||||
parserTermTemp = (TERM *)0;
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
TerminalAbort(void)
|
||||
#else
|
||||
TerminalAbort()
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "TerminalAbort() [%s:%d]", file, line));
|
||||
if (parserTermTemp == (TERM *)0)
|
||||
return;
|
||||
|
||||
DestroyTerminal(parserTermTemp);
|
||||
parserTermTemp = (TERM *)0;
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
TerminalDestroy(void)
|
||||
#else
|
||||
TerminalDestroy()
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "TerminalDestroy() [%s:%d]", file, line));
|
||||
|
||||
if (parserTermTemp != (TERM *)0) {
|
||||
DestroyTerminal(parserTermTemp);
|
||||
parserTermTemp = (TERM *)0;
|
||||
}
|
||||
|
||||
if (parserTermDefault != (TERM *)0) {
|
||||
DestroyTerminal(pTerm);
|
||||
pTerm = parserTermDefault;
|
||||
parserTermDefault = (TERM *)0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ProcessYesNo(char *id, FLAG *flag)
|
||||
#else
|
||||
ProcessYesNo(id, flag)
|
||||
char *id;
|
||||
FLAG *flag;
|
||||
#endif
|
||||
{
|
||||
if (id == (char *)0 || id[0] == '\000')
|
||||
*flag = FLAGFALSE;
|
||||
else if (strcasecmp("yes", id) == 0 || strcasecmp("true", id) == 0 ||
|
||||
strcasecmp("on", id) == 0)
|
||||
*flag = FLAGTRUE;
|
||||
else if (strcasecmp("no", id) == 0 || strcasecmp("false", id) == 0 ||
|
||||
strcasecmp("off", id) == 0)
|
||||
*flag = FLAGFALSE;
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ConfigItemEscape(char *id)
|
||||
#else
|
||||
ConfigItemEscape(id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "ConfigItemEscape(%s) [%s:%d]", id, file, line));
|
||||
|
||||
if (parserConfigTemp->escape != (char *)0)
|
||||
free(parserConfigTemp->escape);
|
||||
|
||||
if ((id == (char *)0) || (*id == '\000')) {
|
||||
parserConfigTemp->escape = (char *)0;
|
||||
return;
|
||||
}
|
||||
if ((parserConfigTemp->escape = StrDup(id)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ConfigItemMaster(char *id)
|
||||
#else
|
||||
ConfigItemMaster(id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "ConfigItemMaster(%s) [%s:%d]", id, file, line));
|
||||
|
||||
if (parserConfigTemp->master != (char *)0)
|
||||
free(parserConfigTemp->master);
|
||||
|
||||
if ((id == (char *)0) || (*id == '\000')) {
|
||||
parserConfigTemp->master = (char *)0;
|
||||
return;
|
||||
}
|
||||
if ((parserConfigTemp->master = StrDup(id)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ConfigItemPort(char *id)
|
||||
#else
|
||||
ConfigItemPort(id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "ConfigItemPort(%s) [%s:%d]", id, file, line));
|
||||
|
||||
if (parserConfigTemp->port != (char *)0)
|
||||
free(parserConfigTemp->port);
|
||||
|
||||
if ((id == (char *)0) || (*id == '\000')) {
|
||||
parserConfigTemp->port = (char *)0;
|
||||
return;
|
||||
}
|
||||
if ((parserConfigTemp->port = StrDup(id)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ConfigItemSslcredentials(char *id)
|
||||
#else
|
||||
ConfigItemSslcredentials(id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "ConfigItemSslcredentials(%s) [%s:%d]", id, file, line));
|
||||
#if HAVE_OPENSSL
|
||||
if (parserConfigTemp->sslcredentials != (char *)0)
|
||||
free(parserConfigTemp->sslcredentials);
|
||||
|
||||
if ((id == (char *)0) || (*id == '\000')) {
|
||||
parserConfigTemp->sslcredentials = (char *)0;
|
||||
return;
|
||||
}
|
||||
if ((parserConfigTemp->sslcredentials = StrDup(id)) == (char *)0)
|
||||
OutOfMem();
|
||||
#else
|
||||
Error
|
||||
("sslcredentials ignored - encryption not compiled into code [%s:%d]",
|
||||
file, line);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ConfigItemSslrequired(char *id)
|
||||
#else
|
||||
ConfigItemSslrequired(id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "ConfigItemSslrequired(%s) [%s:%d]", id, file, line));
|
||||
#if HAVE_OPENSSL
|
||||
ProcessYesNo(id, &(parserConfigTemp->sslrequired));
|
||||
#else
|
||||
Error
|
||||
("sslrequired ignored - encryption not compiled into code [%s:%d]",
|
||||
file, line);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ConfigItemSslenabled(char *id)
|
||||
#else
|
||||
ConfigItemSslenabled(id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "ConfigItemSslenabled(%s) [%s:%d]", id, file, line));
|
||||
#if HAVE_OPENSSL
|
||||
ProcessYesNo(id, &(parserConfigTemp->sslenabled));
|
||||
#else
|
||||
Error("sslenabled ignored - encryption not compiled into code [%s:%d]",
|
||||
file, line);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ConfigItemStriphigh(char *id)
|
||||
#else
|
||||
ConfigItemStriphigh(id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "ConfigItemStriphigh(%s) [%s:%d]", id, file, line));
|
||||
ProcessYesNo(id, &(parserConfigTemp->striphigh));
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ConfigItemUsername(char *id)
|
||||
#else
|
||||
ConfigItemUsername(id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "ConfigItemUsername(%s) [%s:%d]", id, file, line));
|
||||
|
||||
if (parserConfigTemp->username != (char *)0)
|
||||
free(parserConfigTemp->username);
|
||||
|
||||
if ((id == (char *)0) || (*id == '\000')) {
|
||||
parserConfigTemp->username = (char *)0;
|
||||
return;
|
||||
}
|
||||
if ((parserConfigTemp->username = StrDup(id)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
|
||||
SUBST *substData = (SUBST *) 0;
|
||||
|
||||
int
|
||||
#if PROTOTYPES
|
||||
SubstCallback(char c, char **s, int *i)
|
||||
#else
|
||||
SubstCallback(c, s, i)
|
||||
char c;
|
||||
char **s;
|
||||
int *i;
|
||||
#endif
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
if (substData == (SUBST *) 0) {
|
||||
if ((substData =
|
||||
(SUBST *) calloc(1, sizeof(SUBST))) == (SUBST *) 0)
|
||||
OutOfMem();
|
||||
substData->callback = &SubstCallback;
|
||||
substData->tokens['u'] = ISSTRING;
|
||||
substData->tokens['c'] = ISSTRING;
|
||||
}
|
||||
|
||||
if (s != (char **)0) {
|
||||
CONFIG *pc;
|
||||
if (substData->data == (void *)0)
|
||||
return 0;
|
||||
|
||||
pc = (CONFIG *)(substData->data);
|
||||
if (c == 'u') {
|
||||
(*s) = pc->username;
|
||||
retval = 1;
|
||||
} else if (c == 'c') {
|
||||
(*s) = pc->console;
|
||||
retval = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
TerminalItemAttach(char *id)
|
||||
#else
|
||||
TerminalItemAttach(id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "TerminalItemAttach(%s) [%s:%d]", id, file, line));
|
||||
|
||||
if (parserTermTemp->attach != (char *)0)
|
||||
free(parserTermTemp->attach);
|
||||
|
||||
if ((id == (char *)0) || (*id == '\000')) {
|
||||
parserTermTemp->attach = (char *)0;
|
||||
return;
|
||||
}
|
||||
if ((parserTermTemp->attach = StrDup(id)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
TerminalItemAttachsubst(char *id)
|
||||
#else
|
||||
TerminalItemAttachsubst(id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "TerminalItemAttachsubst(%s) [%s:%d]", id, file, line));
|
||||
ProcessSubst(substData, (char **)0, &(parserTermTemp->attachsubst),
|
||||
"attachsubst", id);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
TerminalItemDetach(char *id)
|
||||
#else
|
||||
TerminalItemDetach(id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "TerminalItemDetach(%s) [%s:%d]", id, file, line));
|
||||
|
||||
if (parserTermTemp->detach != (char *)0)
|
||||
free(parserTermTemp->detach);
|
||||
|
||||
if ((id == (char *)0) || (*id == '\000')) {
|
||||
parserTermTemp->detach = (char *)0;
|
||||
return;
|
||||
}
|
||||
if ((parserTermTemp->detach = StrDup(id)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
TerminalItemDetachsubst(char *id)
|
||||
#else
|
||||
TerminalItemDetachsubst(id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "TerminalItemDetachsubst(%s) [%s:%d]", id, file, line));
|
||||
ProcessSubst(substData, (char **)0, &(parserTermTemp->detachsubst),
|
||||
"detachsubst", id);
|
||||
}
|
||||
|
||||
ITEM keyConfig[] = {
|
||||
{"escape", ConfigItemEscape},
|
||||
{"master", ConfigItemMaster},
|
||||
{"port", ConfigItemPort},
|
||||
{"sslcredentials", ConfigItemSslcredentials},
|
||||
{"sslrequired", ConfigItemSslrequired},
|
||||
{"sslenabled", ConfigItemSslenabled},
|
||||
{"striphigh", ConfigItemStriphigh},
|
||||
{"username", ConfigItemUsername},
|
||||
{(char *)0, (void *)0}
|
||||
};
|
||||
|
||||
ITEM keyTerminal[] = {
|
||||
{"attach", TerminalItemAttach},
|
||||
{"attachsubst", TerminalItemAttachsubst},
|
||||
{"detach", TerminalItemDetach},
|
||||
{"detachsubst", TerminalItemDetachsubst},
|
||||
{(char *)0, (void *)0}
|
||||
};
|
||||
|
||||
SECTION sections[] = {
|
||||
{"config", ConfigBegin, ConfigEnd, ConfigAbort, ConfigDestroy,
|
||||
keyConfig},
|
||||
{"terminal", TerminalBegin, TerminalEnd, TerminalAbort,
|
||||
TerminalDestroy, keyTerminal},
|
||||
{(char *)0, (void *)0, (void *)0, (void *)0, (void *)0}
|
||||
};
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ReadConf(char *filename, FLAG verbose)
|
||||
#else
|
||||
ReadConf(filename, verbose)
|
||||
char *filename;
|
||||
FLAG verbose;
|
||||
#endif
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
if ((FILE *)0 == (fp = fopen(filename, "r"))) {
|
||||
if (verbose == FLAGTRUE)
|
||||
Error("could not open `%s'", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
/* initialize the substition bits */
|
||||
SubstCallback('\000', (char **)0, (int *)0);
|
||||
|
||||
parserConfigDefault = pConfig;
|
||||
pConfig = (CONFIG *)0;
|
||||
|
||||
parserTermDefault = pTerm;
|
||||
pTerm = (TERM *)0;
|
||||
|
||||
ParseFile(filename, fp, 0);
|
||||
|
||||
/* shouldn't really happen, but in case i screw up the stuff
|
||||
* ParseFile calls...
|
||||
*/
|
||||
if (pConfig == (CONFIG *)0) {
|
||||
if ((pConfig = (CONFIG *)calloc(1, sizeof(CONFIG)))
|
||||
== (CONFIG *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
|
||||
if (pTerm == (TERM *)0) {
|
||||
if ((pTerm = (TERM *)calloc(1, sizeof(TERM)))
|
||||
== (TERM *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
|
||||
if (fDebug) {
|
||||
#define EMPTYSTR(x) x == (char *)0 ? "(null)" : x
|
||||
#define FLAGSTR(x) x == FLAGTRUE ? "true" : (x == FLAGFALSE ? "false" : "unset")
|
||||
CONDDEBUG((1, "pConfig->username = %s",
|
||||
EMPTYSTR(pConfig->username)));
|
||||
CONDDEBUG((1, "pConfig->master = %s", EMPTYSTR(pConfig->master)));
|
||||
CONDDEBUG((1, "pConfig->port = %s", EMPTYSTR(pConfig->port)));
|
||||
CONDDEBUG((1, "pConfig->escape = %s", EMPTYSTR(pConfig->escape)));
|
||||
CONDDEBUG((1, "pConfig->striphigh = %s",
|
||||
FLAGSTR(pConfig->striphigh)));
|
||||
#if HAVE_OPENSSL
|
||||
CONDDEBUG((1, "pConfig->sslcredentials = %s",
|
||||
EMPTYSTR(pConfig->sslcredentials)));
|
||||
CONDDEBUG((1, "pConfig->sslrequired = %s",
|
||||
FLAGSTR(pConfig->sslrequired)));
|
||||
CONDDEBUG((1, "pConfig->sslenabled = %s",
|
||||
FLAGSTR(pConfig->sslenabled)));
|
||||
#endif
|
||||
CONDDEBUG((1, "pTerm->attach = %s", EMPTYSTR(pTerm->attach)));
|
||||
CONDDEBUG((1, "pTerm->attachsubst = %s",
|
||||
EMPTYSTR(pTerm->attachsubst)));
|
||||
CONDDEBUG((1, "pTerm->detach = %s", EMPTYSTR(pTerm->detach)));
|
||||
CONDDEBUG((1, "pTerm->detachsubst = %s",
|
||||
EMPTYSTR(pTerm->detachsubst)));
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
38
console/readconf.h
Normal file
38
console/readconf.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* $Id: readconf.h,v 5.3 2004/05/25 23:03:25 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
* Maintainer/Enhancer: Bryan Stansell (bryan@conserver.com)
|
||||
*/
|
||||
|
||||
typedef struct config {
|
||||
STRING *name;
|
||||
char *console;
|
||||
char *username;
|
||||
char *master;
|
||||
char *port;
|
||||
char *escape;
|
||||
FLAG striphigh;
|
||||
#if HAVE_OPENSSL
|
||||
char *sslcredentials;
|
||||
FLAG sslrequired;
|
||||
FLAG sslenabled;
|
||||
#endif
|
||||
} CONFIG;
|
||||
|
||||
typedef struct term {
|
||||
STRING *name;
|
||||
char *attach;
|
||||
char *attachsubst;
|
||||
char *detach;
|
||||
char *detachsubst;
|
||||
} TERM;
|
||||
|
||||
extern CONFIG *pConfig;
|
||||
extern TERM *pTerm;
|
||||
extern SUBST *substData;
|
||||
|
||||
extern void ReadConf PARAMS((char *, FLAG));
|
||||
extern void DestroyConfig PARAMS((CONFIG *));
|
||||
extern void DestroyTerminal PARAMS((TERM *));
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
|
||||
%define pkg conserver
|
||||
%define ver 8.1.5
|
||||
%define ver 8.1.6
|
||||
|
||||
# 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.1.5"
|
||||
VERSION="8.1.6"
|
||||
DESC="Console server and client"
|
||||
CLASSES=none
|
||||
ARCH=sparc
|
||||
|
13
test/dotest
13
test/dotest
@ -14,6 +14,7 @@ cleanup()
|
||||
[ "$i" != "conserver.log" ] && [ -f "$i" ] && rm -f "$i";
|
||||
done
|
||||
[ "$exitval" = 0 ] && rm -f conserver.log
|
||||
[ -d 127.0.0.1 ] && sleep 1 && rm -rf 127.0.0.1
|
||||
exit $exitval
|
||||
}
|
||||
|
||||
@ -25,7 +26,7 @@ dotest()
|
||||
eval "$2" > test.out 2>&1
|
||||
else
|
||||
echo "$1" | \
|
||||
../console/console -M 127.0.0.1 -p 7777 shell > test.out 2>&1
|
||||
../console/console -n -C /dev/null -M 127.0.0.1 -p 7777 shell > test.out 2>&1
|
||||
fi
|
||||
if [ "$record" ]; then
|
||||
echo "recorded"
|
||||
@ -72,7 +73,7 @@ sleep 3
|
||||
|
||||
[ ! -d results ] && mkdir results
|
||||
|
||||
dotest EVAL "../console/console -M 127.0.0.1 -p 7777 -u | sed -e 's/[0-9][0-9]*//g' -e 's/[ ][ ]*/ /g'"
|
||||
dotest EVAL "../console/console -n -C /dev/null -M 127.0.0.1 -p 7777 -u | sed -e 's/[0-9][0-9]*//g' -e 's/[ ][ ]*/ /g'"
|
||||
dotest 'c?c.'
|
||||
dotest 'cl?c.'
|
||||
dotest 'cdc.'
|
||||
@ -84,14 +85,14 @@ cp test2.cf c.cf
|
||||
kill -1 $pid
|
||||
sleep 3
|
||||
|
||||
dotest EVAL "../console/console -M 127.0.0.1 -p 7777 -u | sed -e 's/[0-9][0-9]*//g' -e 's/[ ][ ]*/ /g'"
|
||||
dotest EVAL "../console/console -n -C /dev/null -M 127.0.0.1 -p 7777 -u | sed -e 's/[0-9][0-9]*//g' -e 's/[ ][ ]*/ /g'"
|
||||
dotest 'c?c.'
|
||||
dotest 'cl?c.'
|
||||
dotest 'cdc.'
|
||||
dotest 'coc.'
|
||||
|
||||
dotest EVAL "echo 'tu.' | ../console/console -M 127.0.0.1 -p 7777 -e 'tu' shell"
|
||||
dotest EVAL "../console/console -M 127.0.0.1 -p 7777 -R | sed -e 's/ [^ ]*$//'"
|
||||
dotest EVAL "../console/console -M 127.0.0.1 -p 7777 -x | sed -e 's/ on [^ ]* */ on /'"
|
||||
dotest EVAL "echo 'tu.' | ../console/console -n -C /dev/null -M 127.0.0.1 -p 7777 -e 'tu' shell"
|
||||
dotest EVAL "../console/console -n -C /dev/null -M 127.0.0.1 -p 7777 -R | sed -e 's/ [^ ]*$//'"
|
||||
dotest EVAL "../console/console -n -C /dev/null -M 127.0.0.1 -p 7777 -x | sed -e 's/ on [^ ]* */ on /'"
|
||||
|
||||
cleanup
|
||||
|
Loading…
Reference in New Issue
Block a user