mirror of
https://github.com/bstansell/conserver.git
synced 2024-12-20 21:33:08 +00:00
Imported from conserver-8.0.1.tar.gz
This commit is contained in:
parent
4f71385126
commit
de2e2fd33c
25
CHANGES
25
CHANGES
@ -1,6 +1,29 @@
|
||||
CHANGES
|
||||
=======
|
||||
|
||||
version 8.0.1 (Sep 29, 2003):
|
||||
- fixed bug in access list parsing where multiple addresses per
|
||||
line can cause errors - reported by Jay McCanta
|
||||
<mccantaj@amgen.com>
|
||||
- changed client password prompt to show hostname passed down by
|
||||
the server - suggested by Toby Gerhart <toby.gerhart@eds.com>
|
||||
- fixed bug where remote console names were only search for
|
||||
substring matches - reported by Toby Gerhart
|
||||
<toby.gerhart@eds.com>
|
||||
- the server -M option wasn't being used properly to limit the
|
||||
consoles managed by the host
|
||||
- added 'initcmd' console option which allows a command to
|
||||
interact with a console right after a console is opened -
|
||||
suggested by Greg Woods <woods@weird.com>
|
||||
- added the chat program contributed by Greg Woods
|
||||
<woods@weird.com> to the contrib/chat directory
|
||||
- added WUNTRACED to waitpid() for catching suspended processes
|
||||
- reworded some client/server messages to be clearer
|
||||
- embedded non-printable characters in break lists now display
|
||||
correctly when '^Ecl?' is used
|
||||
- in case client aborts unexpectedly, terminal state should
|
||||
now be restored to normal
|
||||
|
||||
version 8.0.0 (Sep 22, 2003):
|
||||
- better error messages and management of the user's password
|
||||
- 8.0.0-beta4 mistakenly lost conserver.passwd usage
|
||||
@ -517,5 +540,5 @@ before version 6.05:
|
||||
and enhancements of various types were applied.
|
||||
|
||||
#
|
||||
# $Id: CHANGES,v 1.103 2003-09-22 10:42:00-07 bryan Exp $
|
||||
# $Id: CHANGES,v 1.109 2003-09-29 08:41:20-07 bryan Exp $
|
||||
#
|
||||
|
9
INSTALL
9
INSTALL
@ -10,6 +10,13 @@ Upgrading?
|
||||
new features added to the client if you're considering *not*
|
||||
upgrading.
|
||||
|
||||
Version 8.0.1
|
||||
|
||||
- There's a slight client/server protocol change to implement
|
||||
the new 'initcmd' console option. If you use this
|
||||
functionality with an 8.0.0 client, you'll run into a
|
||||
compatibility problem while the 'initcmd' command is running.
|
||||
|
||||
Version 8.0.0
|
||||
|
||||
- The client/server protocol has been rearchitected. You *MUST*
|
||||
@ -239,5 +246,5 @@ Other Information And Gotchas
|
||||
|
||||
|
||||
#
|
||||
# $Id: INSTALL,v 1.32 2003-08-23 11:20:55-07 bryan Exp $
|
||||
# $Id: INSTALL,v 1.33 2003-09-28 17:50:05-07 bryan Exp $
|
||||
#
|
||||
|
@ -25,6 +25,12 @@ autologin:
|
||||
autologin.install:
|
||||
( cd autologin && $(MAKE) install $(MAKE_FLAGS) ) || exit 1;
|
||||
|
||||
chat:
|
||||
( cd contrib/chat && $(MAKE) $@ $(MAKE_FLAGS) ) || exit 1;
|
||||
|
||||
chat.install:
|
||||
( cd contrib/chat && $(MAKE) install $(MAKE_FLAGS) ) || exit 1;
|
||||
|
||||
test:
|
||||
( cd test && ./dotest ) || exit 1
|
||||
|
||||
|
6
TODO
6
TODO
@ -74,10 +74,6 @@ Bryan Stansell
|
||||
- suggestions by Trevor Fiatal <trevor@seven.com>
|
||||
- include server hostname on 'console -x' output
|
||||
|
||||
- ability to configure strings to be sent to a console whenever it is
|
||||
(re)opened (eg. a termserver login) : Greg A. Woods
|
||||
<woods@planix.com>
|
||||
|
||||
- ability to configure strings to be sent to a console periodically :
|
||||
Greg A. Woods <woods@planix.com>
|
||||
|
||||
@ -85,5 +81,5 @@ Bryan Stansell
|
||||
<woods@planix.com>
|
||||
|
||||
#
|
||||
# $Id: TODO,v 1.36 2003-08-24 15:11:03-07 bryan Exp $
|
||||
# $Id: TODO,v 1.37 2003-09-28 12:23:23-07 bryan Exp $
|
||||
#
|
||||
|
3
configure
vendored
3
configure
vendored
@ -6762,7 +6762,7 @@ done
|
||||
|
||||
|
||||
|
||||
ac_config_files="$ac_config_files Makefile conserver/Makefile conserver.cf/Makefile console/Makefile autologin/Makefile"
|
||||
ac_config_files="$ac_config_files Makefile conserver/Makefile conserver.cf/Makefile console/Makefile autologin/Makefile contrib/chat/Makefile"
|
||||
|
||||
ac_config_files="$ac_config_files conserver/conserver.rc"
|
||||
|
||||
@ -7295,6 +7295,7 @@ do
|
||||
"conserver.cf/Makefile" ) CONFIG_FILES="$CONFIG_FILES conserver.cf/Makefile" ;;
|
||||
"console/Makefile" ) CONFIG_FILES="$CONFIG_FILES console/Makefile" ;;
|
||||
"autologin/Makefile" ) CONFIG_FILES="$CONFIG_FILES autologin/Makefile" ;;
|
||||
"contrib/chat/Makefile" ) CONFIG_FILES="$CONFIG_FILES contrib/chat/Makefile" ;;
|
||||
"conserver/conserver.rc" ) CONFIG_FILES="$CONFIG_FILES conserver/conserver.rc" ;;
|
||||
"config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
|
||||
*) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
|
||||
|
@ -513,6 +513,6 @@ AC_CHECK_FUNCS(getaudit getaudit_addr)
|
||||
|
||||
|
||||
dnl ### Create output files. #######################################
|
||||
AC_CONFIG_FILES([Makefile conserver/Makefile conserver.cf/Makefile console/Makefile autologin/Makefile])
|
||||
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
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" $Id: conserver.cf.man,v 1.41 2003-09-21 15:05:48-07 bryan Exp $
|
||||
.TH CONSERVER.CF 5 "2003-09-21" "conserver-8.0.0" "conserver"
|
||||
.\" $Id: conserver.cf.man,v 1.42 2003-09-28 12:23:04-07 bryan Exp $
|
||||
.TH CONSERVER.CF 5 "2003-09-28" "conserver-8.0.1" "conserver"
|
||||
.SH NAME
|
||||
conserver.cf \- console configuration file for
|
||||
.BR conserver (8)
|
||||
@ -420,6 +420,21 @@ The default block defined using the name
|
||||
is applied to the current console or default block.
|
||||
The included default block must be previously defined.
|
||||
.TP
|
||||
.B initcmd
|
||||
.RI [ " command "
|
||||
| "" ]
|
||||
.br
|
||||
Invoke
|
||||
.I command
|
||||
as soon as the console is brought up, redirecting the console
|
||||
to stdin, stdout, and stderr of
|
||||
.IR command .
|
||||
The
|
||||
.I command
|
||||
is passed as an argument to ``/bin/sh -ce''.
|
||||
If the null string (``""'') is used, the command is unset and
|
||||
nothing is invoked.
|
||||
.TP
|
||||
.B logfile
|
||||
.RI [ " filename "
|
||||
| "" ]
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" $Id: conserver.passwd.man,v 1.9 2003-07-04 13:20:52-07 bryan Exp $
|
||||
.TH CONSERVER.PASSWD 5 "2003-07-04" "conserver-8.0.0" "conserver"
|
||||
.TH CONSERVER.PASSWD 5 "2003-07-04" "conserver-8.0.1" "conserver"
|
||||
.SH NAME
|
||||
conserver.passwd \- user access information for
|
||||
.BR conserver (8)
|
||||
|
@ -183,11 +183,11 @@
|
||||
|
||||
<H3>Downloading</H3>
|
||||
|
||||
<P>The current version, released on Sep 22, 2003, is <A
|
||||
href="8.0.0.tar.gz">8.0.0.tar.gz</A>. You can get it via
|
||||
<P>The current version, released on Sep 29, 2003, is <A
|
||||
href="8.0.1.tar.gz">8.0.1.tar.gz</A>. You can get it via
|
||||
<A href=
|
||||
"ftp://ftp.conserver.com/conserver/8.0.0.tar.gz">FTP</A>
|
||||
or <A href="8.0.0.tar.gz">HTTP</A>. See the <A href=
|
||||
"ftp://ftp.conserver.com/conserver/8.0.1.tar.gz">FTP</A>
|
||||
or <A href="8.0.1.tar.gz">HTTP</A>. See the <A href=
|
||||
"CHANGES">CHANGES</A> file for information on the latest
|
||||
updates.</P>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: client.c,v 5.69 2003-08-15 14:24:39-07 bryan Exp $
|
||||
* $Id: client.c,v 5.70 2003-09-28 08:42:06-07 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -52,36 +52,40 @@ int deny_severity = LOG_WARNING;
|
||||
|
||||
/* find the next guy who wants to write on the console (ksb)
|
||||
*/
|
||||
CONSCLIENT *
|
||||
void
|
||||
#if PROTOTYPES
|
||||
FindWrite(CONSCLIENT *pCL)
|
||||
FindWrite(CONSENT *pCE)
|
||||
#else
|
||||
FindWrite(pCL)
|
||||
CONSCLIENT *pCL;
|
||||
FindWrite(pCE)
|
||||
CONSENT *pCE;
|
||||
#endif
|
||||
{
|
||||
/* return the first guy to have the `want write' bit set
|
||||
CONSCLIENT *pCL;
|
||||
|
||||
/* make the first guy to have the `want write' bit set the writer
|
||||
* (tell him of the promotion, too) we could look for the
|
||||
* most recent or some such... I guess it doesn't matter that
|
||||
* much.
|
||||
*/
|
||||
for ( /*passed in */ ; (CONSCLIENT *)0 != pCL; pCL = pCL->pCLnext) {
|
||||
if (pCE->pCLwr != (CONSCLIENT *)0 || pCE->fronly ||
|
||||
!(pCE->fup && pCE->ioState == ISNORMAL &&
|
||||
pCE->initfile == (CONSFILE *)0))
|
||||
return;
|
||||
|
||||
for (pCL = pCE->pCLon; (CONSCLIENT *)0 != pCL; pCL = pCL->pCLnext) {
|
||||
if (!pCL->fwantwr || pCL->fro)
|
||||
continue;
|
||||
if (!(pCL->pCEto->fup && pCL->pCEto->ioState == ISNORMAL) ||
|
||||
pCL->pCEto->fronly)
|
||||
break;
|
||||
pCL->fwantwr = 0;
|
||||
pCL->fwr = 1;
|
||||
if (pCL->pCEto->nolog) {
|
||||
if (pCE->nolog) {
|
||||
FileWrite(pCL->fd, "\r\n[attached (nologging)]\r\n", -1);
|
||||
} else {
|
||||
FileWrite(pCL->fd, "\r\n[attached]\r\n", -1);
|
||||
}
|
||||
TagLogfileAct(pCL->pCEto, "%s attached", pCL->acid->string);
|
||||
return pCL;
|
||||
TagLogfileAct(pCE, "%s attached", pCL->acid->string);
|
||||
pCE->pCLwr = pCL;
|
||||
return;
|
||||
}
|
||||
return (CONSCLIENT *)0;
|
||||
}
|
||||
|
||||
/* replay last iBack lines of the log file upon connect to console (ksb)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: client.h,v 5.31 2003-08-24 13:00:50-07 bryan Exp $
|
||||
* $Id: client.h,v 5.32 2003-09-28 08:41:20-07 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -85,5 +85,5 @@ typedef struct client { /* Connection Information: */
|
||||
|
||||
extern void Replay PARAMS((CONSFILE *, CONSFILE *, int));
|
||||
extern void HelpUser PARAMS((CONSCLIENT *));
|
||||
extern CONSCLIENT *FindWrite PARAMS((CONSCLIENT *));
|
||||
extern void FindWrite PARAMS((CONSENT *));
|
||||
extern int ClientAccessOk PARAMS((CONSCLIENT *));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: consent.c,v 5.125 2003-08-15 14:24:39-07 bryan Exp $
|
||||
* $Id: consent.c,v 5.127 2003-09-28 10:37:20-07 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -248,6 +248,187 @@ TtyDev(pCE)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
StopInit(CONSENT *pCE)
|
||||
#else
|
||||
StopInit(pCE)
|
||||
CONSENT *pCE;
|
||||
#endif
|
||||
{
|
||||
if (pCE->initcmd == (char *)0)
|
||||
return;
|
||||
|
||||
if (pCE->initpid != 0) {
|
||||
Verbose("[%s] initcmd terminated: pid %lu", pCE->server,
|
||||
(unsigned long)pCE->initpid);
|
||||
CONDDEBUG((1, "StopInit(): sending initcmd pid %lu signal %d",
|
||||
(unsigned long)pCE->initpid, SIGHUP));
|
||||
kill(pCE->initpid, SIGHUP);
|
||||
pCE->initpid = 0;
|
||||
}
|
||||
|
||||
if (pCE->initfile != (CONSFILE *)0) {
|
||||
int initfile = FileFDNum(pCE->initfile);
|
||||
FD_CLR(initfile, &rinit);
|
||||
initfile = FileFDOutNum(pCE->initfile);
|
||||
FD_CLR(initfile, &winit);
|
||||
FileClose(&pCE->initfile);
|
||||
pCE->initfile = (CONSFILE *)0;
|
||||
}
|
||||
}
|
||||
|
||||
/* invoke the initcmd command */
|
||||
void
|
||||
#if PROTOTYPES
|
||||
StartInit(CONSENT *pCE)
|
||||
#else
|
||||
StartInit(pCE)
|
||||
CONSENT *pCE;
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
pid_t iNewGrp;
|
||||
extern char **environ;
|
||||
int pin[2];
|
||||
int pout[2];
|
||||
static char *apcArgv[] = {
|
||||
"/bin/sh", "-ce", (char *)0, (char *)0
|
||||
};
|
||||
|
||||
if (pCE->initcmd == (char *)0)
|
||||
return;
|
||||
|
||||
/* this should never happen, but hey, just in case */
|
||||
if (pCE->initfile != (CONSFILE *)0 || pCE->initpid != 0) {
|
||||
Error("[%s] StartInit(): initpid/initfile sync error",
|
||||
pCE->server);
|
||||
StopInit(pCE);
|
||||
}
|
||||
|
||||
if (pCE->pCLwr != (CONSCLIENT *)0) {
|
||||
CONSCLIENT *pCL = pCE->pCLwr;
|
||||
pCL->fwr = 0;
|
||||
pCL->fwantwr = 1;
|
||||
/*
|
||||
FileWrite(pCL->fd,
|
||||
"[forced to `spy' mode by initialization command]\r\n",
|
||||
-1);
|
||||
TagLogfileAct(pCE, "initialization command bumped %s",
|
||||
pCL->acid->string);
|
||||
*/
|
||||
pCE->pCLwr = (CONSCLIENT *)0;
|
||||
}
|
||||
|
||||
/* pin[0] = parent read, pin[1] = child write */
|
||||
if (pipe(pin) != 0) {
|
||||
Error("[%s] StartInit(): pipe(): %s", pCE->server,
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
/* pout[0] = child read, pout[l] = parent write */
|
||||
if (pipe(pout) != 0) {
|
||||
close(pin[0]);
|
||||
close(pin[1]);
|
||||
Error("[%s] StartInit(): pipe(): %s", pCE->server,
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
switch (pCE->initpid = fork()) {
|
||||
case -1:
|
||||
pCE->initpid = 0;
|
||||
return;
|
||||
case 0:
|
||||
thepid = getpid();
|
||||
break;
|
||||
default:
|
||||
close(pout[0]);
|
||||
close(pin[1]);
|
||||
if ((pCE->initfile =
|
||||
FileOpenPipe(pin[0], pout[1])) == (CONSFILE *)0) {
|
||||
Error("[%s] FileOpenPipe(%d,%d) failed: forcing down",
|
||||
pCE->server, pin[0], pout[1]);
|
||||
close(pin[0]);
|
||||
close(pout[1]);
|
||||
kill(pCE->initpid, SIGHUP);
|
||||
pCE->initpid = 0;
|
||||
return;
|
||||
}
|
||||
Verbose("[%s] initcmd started: pid %lu", pCE->server,
|
||||
(unsigned long)pCE->initpid);
|
||||
FD_SET(pin[0], &rinit);
|
||||
if (maxfd < pin[0] + 1)
|
||||
maxfd = pin[0] + 1;
|
||||
fflush(stderr);
|
||||
return;
|
||||
}
|
||||
|
||||
close(pin[0]);
|
||||
close(pout[1]);
|
||||
|
||||
/* put the signals back that we ignore (trapped auto-reset to default)
|
||||
*/
|
||||
SimpleSignal(SIGQUIT, SIG_DFL);
|
||||
SimpleSignal(SIGINT, SIG_DFL);
|
||||
SimpleSignal(SIGPIPE, SIG_DFL);
|
||||
#if defined(SIGTTOU)
|
||||
SimpleSignal(SIGTTOU, SIG_DFL);
|
||||
#endif
|
||||
#if defined(SIGTTIN)
|
||||
SimpleSignal(SIGTTIN, SIG_DFL);
|
||||
#endif
|
||||
#if defined(SIGTSTP)
|
||||
SimpleSignal(SIGTSTP, SIG_DFL);
|
||||
#endif
|
||||
#if defined(SIGPOLL)
|
||||
SimpleSignal(SIGPOLL, SIG_DFL);
|
||||
#endif
|
||||
|
||||
/* setup new process with clean file descriptors
|
||||
*/
|
||||
i = GetMaxFiles();
|
||||
for ( /* i above */ ; --i > 2;) {
|
||||
if (i != pout[0] && i != pin[1])
|
||||
close(i);
|
||||
}
|
||||
/* leave 2 until we have to close it */
|
||||
close(1);
|
||||
close(0);
|
||||
|
||||
# if HAVE_SETSID
|
||||
iNewGrp = setsid();
|
||||
if (-1 == iNewGrp) {
|
||||
Error("[%s] setsid(): %s", pCE->server, strerror(errno));
|
||||
iNewGrp = getpid();
|
||||
}
|
||||
# else
|
||||
iNewGrp = getpid();
|
||||
# endif
|
||||
|
||||
if (dup(pout[0]) != 0 || dup(pin[1]) != 1) {
|
||||
Error("[%s] StartInit(): fd sync error", pCE->server);
|
||||
Bye(EX_OSERR);
|
||||
}
|
||||
close(pout[0]);
|
||||
close(pin[1]);
|
||||
|
||||
tcsetpgrp(0, iNewGrp);
|
||||
|
||||
apcArgv[2] = pCE->initcmd;
|
||||
|
||||
close(2);
|
||||
dup(1); /* better be 2, but it is too late now */
|
||||
|
||||
execve(apcArgv[0], apcArgv, environ);
|
||||
Error("[%s] execve(%s): %s", pCE->server, apcArgv[2], strerror(errno));
|
||||
Bye(EX_OSERR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* setup a virtual device (ksb)
|
||||
*/
|
||||
static int
|
||||
@ -424,11 +605,13 @@ ConsDown(pCE, downHard, force)
|
||||
#endif
|
||||
{
|
||||
if (force != FLAGTRUE &&
|
||||
!(FileBufEmpty(pCE->fdlog) && FileBufEmpty(pCE->cofile))) {
|
||||
!(FileBufEmpty(pCE->fdlog) && FileBufEmpty(pCE->cofile) &&
|
||||
FileBufEmpty(pCE->initfile))) {
|
||||
pCE->ioState = ISFLUSHING;
|
||||
return;
|
||||
}
|
||||
|
||||
StopInit(pCE);
|
||||
if (pCE->ipid != 0) {
|
||||
CONDDEBUG((1, "ConsDown(): sending pid %lu signal %d",
|
||||
(unsigned long)pCE->ipid, SIGHUP));
|
||||
@ -674,6 +857,9 @@ ConsInit(pCE)
|
||||
Msg("[%s] console up", pCE->server);
|
||||
pCE->downHard = FLAGFALSE;
|
||||
}
|
||||
|
||||
if (pCE->ioState == ISNORMAL)
|
||||
StartInit(pCE);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: consent.h,v 5.46 2003-08-18 20:01:16-07 bryan Exp $
|
||||
* $Id: consent.h,v 5.47 2003-09-28 08:43:04-07 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -93,12 +93,11 @@ typedef struct consent { /* console information */
|
||||
unsigned short port; /* port number */
|
||||
/* type == EXEC */
|
||||
char *exec; /* exec command */
|
||||
/* */
|
||||
/* global stuff */
|
||||
char *master; /* master hostname */
|
||||
/* */
|
||||
unsigned short breakNum; /* break type [1-9] */
|
||||
/* */
|
||||
char *logfile; /* logfile */
|
||||
char *initcmd; /* initcmd command */
|
||||
/* timestamp stuff */
|
||||
int mark; /* Mark (chime) interval */
|
||||
long nextMark; /* Next mark (chime) time */
|
||||
@ -117,6 +116,8 @@ typedef struct consent { /* console information */
|
||||
char *execSlave; /* pseudo-device slave side */
|
||||
int execSlaveFD; /* fd of slave side */
|
||||
pid_t ipid; /* pid of virtual command */
|
||||
pid_t initpid; /* pid of initcmd command */
|
||||
CONSFILE *initfile; /* the command run on init */
|
||||
STRING *wbuf; /* write() buffer */
|
||||
int wbufIAC; /* next IAC location in wbuf */
|
||||
IOSTATE ioState; /* state of the socket */
|
||||
@ -154,3 +155,5 @@ extern void ConsInit PARAMS((CONSENT *));
|
||||
extern void ConsDown PARAMS((CONSENT *, FLAG, FLAG));
|
||||
extern REMOTE *FindUniq PARAMS((REMOTE *));
|
||||
extern void DestroyRemoteConsole PARAMS((REMOTE *));
|
||||
extern void StartInit PARAMS((CONSENT *));
|
||||
extern void StopInit PARAMS((CONSENT *));
|
||||
|
@ -1,6 +1,6 @@
|
||||
.\" @(#)conserver.8 01/06/91 OSU CIS; Thomas A. Fine
|
||||
.\" $Id: conserver.man,v 1.38 2003-09-22 08:33:41-07 bryan Exp $
|
||||
.TH CONSERVER 8 "2003-09-22" "conserver-8.0.0" "conserver"
|
||||
.TH CONSERVER 8 "2003-09-22" "conserver-8.0.1" "conserver"
|
||||
.SH NAME
|
||||
conserver \- console server daemon
|
||||
.SH SYNOPSIS
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: group.c,v 5.248 2003-09-19 08:58:18-07 bryan Exp $
|
||||
* $Id: group.c,v 5.256 2003-09-29 08:39:13-07 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -220,7 +220,8 @@ DisconnectClient(pGE, pCL, message, force)
|
||||
pCEServing->nolog = 0;
|
||||
TagLogfile(pCEServing, "Console logging restored (logout)");
|
||||
}
|
||||
pCEServing->pCLwr = FindWrite(pCEServing->pCLon);
|
||||
pCEServing->pCLwr = (CONSCLIENT *)0;
|
||||
FindWrite(pCEServing);
|
||||
}
|
||||
|
||||
/* mark as unconnected and remove from both
|
||||
@ -802,10 +803,10 @@ ConsoleError(pCE)
|
||||
ConsInit(pCE);
|
||||
|
||||
/* If we didn't succeed, try again later */
|
||||
if (!pCE->fup)
|
||||
pCE->autoReUp = 1;
|
||||
if (pCE->fup)
|
||||
FindWrite(pCE);
|
||||
else
|
||||
pCE->pCLwr = FindWrite(pCE->pCLon);
|
||||
pCE->autoReUp = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -884,8 +885,8 @@ ReUp(pGE, automatic)
|
||||
if (automatic)
|
||||
Msg("[%s] automatic reinitialization", pCE->server);
|
||||
ConsInit(pCE);
|
||||
if (pCE->fup && pCE->ioState == ISNORMAL)
|
||||
pCE->pCLwr = FindWrite(pCE->pCLon);
|
||||
if (pCE->fup)
|
||||
FindWrite(pCE);
|
||||
else if (automatic)
|
||||
pCE->autoReUp = autoReUp;
|
||||
}
|
||||
@ -1131,13 +1132,15 @@ ReapVirt(pGE)
|
||||
int UWbuf;
|
||||
CONSENT *pCE;
|
||||
|
||||
while (-1 != (pid = waitpid(-1, &UWbuf, WNOHANG))) {
|
||||
while (-1 != (pid = waitpid(-1, &UWbuf, WNOHANG | WUNTRACED))) {
|
||||
if (0 == pid) {
|
||||
break;
|
||||
}
|
||||
/* stopped child is just continued
|
||||
*/
|
||||
if (WIFSTOPPED(UWbuf) && 0 == kill(pid, SIGCONT)) {
|
||||
Msg("child pid %lu: stopped, sending SIGCONT",
|
||||
(unsigned long)pid);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1146,6 +1149,15 @@ ReapVirt(pGE)
|
||||
}
|
||||
|
||||
for (pCE = pGE->pCElist; pCE != (CONSENT *)0; pCE = pCE->pCEnext) {
|
||||
if (pid == pCE->initpid) {
|
||||
Verbose("[%s] initcmd terminated: pid %lu", pCE->server,
|
||||
(unsigned long)pCE->initpid);
|
||||
pCE->initpid = 0;
|
||||
StopInit(pCE);
|
||||
FindWrite(pCE);
|
||||
break;
|
||||
}
|
||||
|
||||
if (pid != pCE->ipid)
|
||||
continue;
|
||||
|
||||
@ -1172,11 +1184,12 @@ ReapVirt(pGE)
|
||||
ConsInit(pCE);
|
||||
|
||||
/* If we didn't succeed, try again later */
|
||||
if (!pCE->fup)
|
||||
pCE->autoReUp = 1;
|
||||
if (pCE->fup)
|
||||
FindWrite(pCE);
|
||||
else
|
||||
pCE->pCLwr = FindWrite(pCE->pCLon);
|
||||
pCE->autoReUp = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1640,14 +1653,16 @@ CommandAttach(pGE, pCLServing, pCEServing, tyme)
|
||||
{
|
||||
CONSCLIENT *pCL;
|
||||
|
||||
if (pGE->pCEctl == pCEServing) {
|
||||
FileWrite(pCLServing->fd, "no -- on ctl]\r\n", -1);
|
||||
} else if (!(pCEServing->fup && pCEServing->ioState == ISNORMAL)) {
|
||||
FileWrite(pCLServing->fd, "line to host is down]\r\n", -1);
|
||||
} else if (pCEServing->fronly) {
|
||||
FileWrite(pCLServing->fd, "host is read-only]\r\n", -1);
|
||||
if (pCEServing->fronly) {
|
||||
FileWrite(pCLServing->fd, "console is read-only]\r\n", -1);
|
||||
} else if (pCEServing->initfile != (CONSFILE *)0 ||
|
||||
pCEServing->ioState == INCONNECT) {
|
||||
FileWrite(pCLServing->fd, "read-only -- initializing]\r\n", -1);
|
||||
pCLServing->fwantwr = 1;
|
||||
} else if (pCLServing->fro) {
|
||||
FileWrite(pCLServing->fd, "read-only]\r\n", -1);
|
||||
} else if (!(pCEServing->fup && pCEServing->ioState == ISNORMAL)) {
|
||||
FileWrite(pCLServing->fd, "line to console is down]\r\n", -1);
|
||||
} else if ((CONSCLIENT *)0 == (pCL = pCEServing->pCLwr)) {
|
||||
pCEServing->pCLwr = pCLServing;
|
||||
pCLServing->fwr = 1;
|
||||
@ -1685,8 +1700,14 @@ CommandChangeFlow(pGE, pCLServing, pCEServing, tyme)
|
||||
struct termios sbuf;
|
||||
int cofile;
|
||||
|
||||
if (pCEServing->type != DEVICE && pCEServing->type != EXEC)
|
||||
if (!pCLServing->fwr) {
|
||||
FileWrite(pCLServing->fd, "attach to change flow]\r\n", -1);
|
||||
return;
|
||||
}
|
||||
if (pCEServing->type != DEVICE && pCEServing->type != EXEC) {
|
||||
FileWrite(pCLServing->fd, "ok]\r\n", -1);
|
||||
return;
|
||||
}
|
||||
cofile = FileFDNum(pCEServing->cofile);
|
||||
if (-1 == tcgetattr(cofile, &sbuf)) {
|
||||
FileWrite(pCLServing->fd, "failed]\r\n", -1);
|
||||
@ -1694,15 +1715,18 @@ CommandChangeFlow(pGE, pCLServing, pCEServing, tyme)
|
||||
}
|
||||
if (0 != (sbuf.c_iflag & IXON)) {
|
||||
sbuf.c_iflag &= ~(IXON);
|
||||
FileWrite(pCLServing->fd, "ixon OFF]\r\n", -1);
|
||||
} else {
|
||||
sbuf.c_iflag |= IXON;
|
||||
FileWrite(pCLServing->fd, "ixon ON]\r\n", -1);
|
||||
}
|
||||
if (-1 == tcsetattr(cofile, TCSANOW, &sbuf)) {
|
||||
FileWrite(pCLServing->fd, "failed]\r\n", -1);
|
||||
return;
|
||||
}
|
||||
if ((sbuf.c_iflag & IXON) == 0) {
|
||||
FileWrite(pCLServing->fd, "ixon OFF]\r\n", -1);
|
||||
} else {
|
||||
FileWrite(pCLServing->fd, "ixon ON]\r\n", -1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -1719,11 +1743,15 @@ CommandDown(pGE, pCLServing, pCEServing, tyme)
|
||||
{
|
||||
CONSCLIENT *pCL;
|
||||
|
||||
if (pGE->pCEctl == pCEServing) {
|
||||
FileWrite(pCLServing->fd, "no -- on ctl]\r\n", -1);
|
||||
return;
|
||||
}
|
||||
if (!pCLServing->fwr && !pCEServing->fronly && !pCLServing->fro) {
|
||||
/* if client is read-only OR
|
||||
* console is read-only OR
|
||||
* (console is up, normal state, and not running command AND
|
||||
* client isn't the writer)
|
||||
* then just pop out an "error" message
|
||||
*/
|
||||
if (pCLServing->fro || pCEServing->fronly ||
|
||||
(pCEServing->fup && pCEServing->ioState == ISNORMAL &&
|
||||
pCEServing->initfile == (CONSFILE *)0 && !pCLServing->fwr)) {
|
||||
FileWrite(pCLServing->fd, "attach to down line]\r\n", -1);
|
||||
return;
|
||||
}
|
||||
@ -1812,17 +1840,19 @@ CommandForce(pGE, pCLServing, pCEServing, tyme)
|
||||
{
|
||||
CONSCLIENT *pCL;
|
||||
|
||||
if (pGE->pCEctl == pCEServing) {
|
||||
FileWrite(pCLServing->fd, "no -- on ctl]\r\n", -1);
|
||||
return;
|
||||
} else if (pCLServing->fro) {
|
||||
if (pCLServing->fro) {
|
||||
FileWrite(pCLServing->fd, "read-only]\r\n", -1);
|
||||
return;
|
||||
} else if (pCEServing->initfile != (CONSFILE *)0 ||
|
||||
pCEServing->ioState == INCONNECT) {
|
||||
FileWrite(pCLServing->fd, "read-only -- initializing]\r\n", -1);
|
||||
pCLServing->fwantwr = 1;
|
||||
return;
|
||||
} else if (pCEServing->fronly) {
|
||||
FileWrite(pCLServing->fd, "host is read-only]\r\n", -1);
|
||||
FileWrite(pCLServing->fd, "console is read-only]\r\n", -1);
|
||||
return;
|
||||
} else if (!(pCEServing->fup && pCEServing->ioState == ISNORMAL)) {
|
||||
FileWrite(pCLServing->fd, "line to host is down]\r\n", -1);
|
||||
FileWrite(pCLServing->fd, "line to console is down]\r\n", -1);
|
||||
return;
|
||||
}
|
||||
if ((CONSCLIENT *)0 != (pCL = pCEServing->pCLwr)) {
|
||||
@ -1908,7 +1938,12 @@ CommandHosts(pGE, pCLServing, pCEServing, tyme)
|
||||
sprintf((char *)buf, " %-24.24s %c %-4.4s %-.40s\r\n", pCE->server,
|
||||
pCE == pCEServing ? '*' : ' ', (pCE->fup &&
|
||||
pCE->ioState ==
|
||||
ISNORMAL) ? "up" : "down",
|
||||
ISNORMAL) ? (pCE->
|
||||
initfile ==
|
||||
(CONSFILE *)0
|
||||
? "up" :
|
||||
"init") :
|
||||
"down",
|
||||
pCE->pCLwr ? pCE->pCLwr->acid->string : pCE->
|
||||
pCLon ? "<spies>" : "<none>");
|
||||
FileWrite(pCLServing->fd, (char *)buf, -1);
|
||||
@ -1978,8 +2013,10 @@ CommandInfo(pGE, pCLServing, pCEServing, tyme)
|
||||
|
||||
FilePrint(pCLServing->fd, ":%s:%s:%s,%s,%s,%s,%d,%d:%d:%s:",
|
||||
((pCE->fup &&
|
||||
pCE->ioState == ISNORMAL) ? "up" : "down"),
|
||||
(pCE->fronly ? "ro" : "rw"),
|
||||
pCE->ioState == ISNORMAL) ? (pCE->initfile ==
|
||||
(CONSFILE *)0 ? "up" :
|
||||
"init")
|
||||
: "down"), (pCE->fronly ? "ro" : "rw"),
|
||||
(pCE->logfile == (char *)0 ? "" : pCE->logfile),
|
||||
(pCE->nolog ? "nolog" : "log"),
|
||||
(pCE->activitylog == FLAGTRUE ? "act" : "noact"),
|
||||
@ -2020,11 +2057,10 @@ CommandInfo(pGE, pCLServing, pCEServing, tyme)
|
||||
s = BuildTmpString(",autoreinit");
|
||||
if (pCE->unloved == FLAGTRUE)
|
||||
s = BuildTmpString(",unloved");
|
||||
FilePrint(pCLServing->fd, ":");
|
||||
if (s != (char *)0)
|
||||
FilePrint(pCLServing->fd, "%s", s + 1);
|
||||
FilePrint(pCLServing->fd, ":%s:%s\r\n",
|
||||
(s == (char *)0 ? "" : s + 1),
|
||||
(pCE->initcmd == (char *)0 ? "" : pCE->initcmd));
|
||||
BuildTmpString((char *)0);
|
||||
FilePrint(pCLServing->fd, "\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2052,7 +2088,7 @@ CommandLogging(pGE, pCLServing, pCEServing, tyme)
|
||||
pCLServing->acid->string);
|
||||
}
|
||||
} else {
|
||||
FilePrint(pCLServing->fd, "read-only]\r\n");
|
||||
FilePrint(pCLServing->fd, "attach to toggle logging]\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2070,11 +2106,15 @@ CommandOpen(pGE, pCLServing, pCEServing, tyme)
|
||||
{
|
||||
CONSCLIENT *pCL;
|
||||
|
||||
if (pGE->pCEctl == pCEServing) {
|
||||
FileWrite(pCLServing->fd, "no -- on ctl]\r\n", -1);
|
||||
return;
|
||||
}
|
||||
if (pCEServing->fup && !pCLServing->fwr) {
|
||||
/* if client is read-only OR
|
||||
* console is read-only OR
|
||||
* (console is up, normal state, and not running command AND
|
||||
* client isn't the writer)
|
||||
* then just pop out an "error" message
|
||||
*/
|
||||
if (pCLServing->fro || pCEServing->fronly ||
|
||||
(pCEServing->fup && pCEServing->ioState == ISNORMAL &&
|
||||
pCEServing->initfile == (CONSFILE *)0 && !pCLServing->fwr)) {
|
||||
FileWrite(pCLServing->fd, "attach to reopen]\r\n", -1);
|
||||
return;
|
||||
}
|
||||
@ -2082,8 +2122,11 @@ CommandOpen(pGE, pCLServing, pCEServing, tyme)
|
||||
* change fd's
|
||||
*/
|
||||
ConsInit(pCEServing);
|
||||
if (!(pCEServing->fup && pCEServing->ioState == ISNORMAL)) {
|
||||
FileWrite(pCLServing->fd, "line to host is down]\r\n", -1);
|
||||
if (pCEServing->initfile != (CONSFILE *)0 ||
|
||||
pCEServing->ioState == INCONNECT) {
|
||||
FileWrite(pCLServing->fd, "read-only -- initializing]\r\n", -1);
|
||||
} else if (!(pCEServing->fup && pCEServing->ioState == ISNORMAL)) {
|
||||
FileWrite(pCLServing->fd, "line to console is down]\r\n", -1);
|
||||
} else if (pCEServing->fronly) {
|
||||
FileWrite(pCLServing->fd, "up read-only]\r\n", -1);
|
||||
} else if ((CONSCLIENT *)0 == (pCL = pCEServing->pCLwr)) {
|
||||
@ -2218,6 +2261,12 @@ DoConsoleRead(pCEServing)
|
||||
WriteLog(pCEServing, (char *)acIn, nr);
|
||||
}
|
||||
|
||||
/* if we have a command running, interface with it and then
|
||||
* allow the normal stuff to happen (so folks can watch)
|
||||
*/
|
||||
if (pCEServing->initfile != (CONSFILE *)0)
|
||||
FileWrite(pCEServing->initfile, (char *)acIn, nr);
|
||||
|
||||
/* output all console info nobody is attached
|
||||
*/
|
||||
if (pCEServing->pCLwr == (CONSCLIENT *)0 &&
|
||||
@ -2250,6 +2299,39 @@ DoConsoleRead(pCEServing)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
DoCommandRead(CONSENT *pCEServing)
|
||||
#else
|
||||
DoCommandRead(pCEServing)
|
||||
CONSENT *pCEServing;
|
||||
#endif
|
||||
{
|
||||
unsigned char acInOrig[BUFSIZ];
|
||||
int nr, i, fd;
|
||||
|
||||
if (pCEServing->initfile == (CONSFILE *)0)
|
||||
return;
|
||||
|
||||
fd = FileFDNum(pCEServing->initfile);
|
||||
|
||||
/* read from command */
|
||||
if ((nr =
|
||||
FileRead(pCEServing->initfile, acInOrig, sizeof(acInOrig))) < 0) {
|
||||
StopInit(pCEServing);
|
||||
FindWrite(pCEServing);
|
||||
return;
|
||||
}
|
||||
CONDDEBUG((1, "DoCommandRead(): read %d bytes from fd %d", nr, fd));
|
||||
|
||||
for (i = 0; i < nr; ++i) {
|
||||
if (pCEServing->striphigh == FLAGTRUE)
|
||||
PutConsole(pCEServing, acInOrig[i] & 127, 1);
|
||||
else
|
||||
PutConsole(pCEServing, acInOrig[i], 1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
DoClientRead(GRPENT *pGE, CONSCLIENT *pCLServing)
|
||||
@ -2408,7 +2490,8 @@ DoClientRead(pGE, pCLServing)
|
||||
pCLServing->acid->string);
|
||||
FileWrite(pCLServing->fd, "ok\r\n", -1);
|
||||
} else {
|
||||
FileWrite(pCLServing->fd, "passwd?\r\n", -1);
|
||||
FilePrint(pCLServing->fd, "passwd? %s\r\n",
|
||||
myHostname);
|
||||
pCLServing->iState = S_PASSWD;
|
||||
}
|
||||
}
|
||||
@ -2496,7 +2579,8 @@ DoClientRead(pGE, pCLServing)
|
||||
pCLServing->fwantwr = 0;
|
||||
TagLogfileAct(pCEServing, "%s detached",
|
||||
pCLServing->acid->string);
|
||||
pCEServing->pCLwr = FindWrite(pCEServing->pCLon);
|
||||
pCEServing->pCLwr = (CONSCLIENT *)0;
|
||||
FindWrite(pCEServing);
|
||||
}
|
||||
|
||||
/* inform operators of the change
|
||||
@ -2528,14 +2612,20 @@ DoClientRead(pGE, pCLServing)
|
||||
|
||||
/* try for attach on new console
|
||||
*/
|
||||
if (pCEServing->fronly) {
|
||||
FileWrite(pCLServing->fd,
|
||||
"[console is read-only]\r\n", -1);
|
||||
} else if (pCEServing->initfile != (CONSFILE *)0 ||
|
||||
pCEServing->ioState == INCONNECT) {
|
||||
pCLServing->fwantwr = 1;
|
||||
FileWrite(pCLServing->fd,
|
||||
"[read-only -- initializing]\r\n", -1);
|
||||
} else
|
||||
if (!
|
||||
(pCEServing->fup &&
|
||||
pCEServing->ioState == ISNORMAL)) {
|
||||
FileWrite(pCLServing->fd,
|
||||
"[line to host is down]\r\n", -1);
|
||||
} else if (pCEServing->fronly) {
|
||||
FileWrite(pCLServing->fd,
|
||||
"[host is read-only]\r\n", -1);
|
||||
"[line to console is down]\r\n", -1);
|
||||
} else if (((CONSCLIENT *)0 == pCEServing->pCLwr)
|
||||
&& !pCLServing->fro) {
|
||||
pCEServing->pCLwr = pCLServing;
|
||||
@ -2546,6 +2636,7 @@ DoClientRead(pGE, pCLServing)
|
||||
TagLogfileAct(pCEServing, "%s attached",
|
||||
pCLServing->acid->string);
|
||||
} else {
|
||||
pCLServing->fwantwr = 1;
|
||||
FileWrite(pCLServing->fd, "[spy]\r\n", -1);
|
||||
}
|
||||
pCLServing->fcon = 1;
|
||||
@ -2774,21 +2865,31 @@ DoClientRead(pGE, pCLServing)
|
||||
" 0 - 0ms, <undefined>\r\n", -1);
|
||||
else {
|
||||
sprintf(ms, "%3d", breakList[i - 1].delay);
|
||||
FmtCtlStr(breakList[i - 1].seq->string,
|
||||
breakList[i - 1].seq->used - 1,
|
||||
acA1);
|
||||
FilePrint(pCLServing->fd,
|
||||
" 0 - %sms, `%s'\r\n", ms,
|
||||
breakList[i - 1].seq->string);
|
||||
acA1->string);
|
||||
}
|
||||
for (i = 0; i < 9; i++) {
|
||||
if (breakList[i].seq->used > 1) {
|
||||
sprintf(ms, "%3d", breakList[i].delay);
|
||||
FmtCtlStr(breakList[i].seq->string,
|
||||
breakList[i].seq->used - 1,
|
||||
acA1);
|
||||
FilePrint(pCLServing->fd,
|
||||
" %d - %sms, `%s'\r\n", i + 1,
|
||||
ms, breakList[i].seq->string);
|
||||
ms, acA1->string);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (pCLServing->fwr) {
|
||||
int bt = acIn[i] - '0';
|
||||
SendBreak(pCLServing, pCEServing, bt);
|
||||
} else
|
||||
FileWrite(pCLServing->fd,
|
||||
"attach to send break]\r\n", -1);
|
||||
}
|
||||
continue;
|
||||
|
||||
@ -2916,15 +3017,10 @@ DoClientRead(pGE, pCLServing)
|
||||
case 'l': /* halt character 1 */
|
||||
if (pCEServing->fronly) {
|
||||
FileWrite(pCLServing->fd,
|
||||
"can't halt read-only host]\r\n",
|
||||
"can't halt read-only console]\r\n",
|
||||
-1);
|
||||
continue;
|
||||
}
|
||||
if (!pCLServing->fwr) {
|
||||
FileWrite(pCLServing->fd,
|
||||
"attach to halt]\r\n", -1);
|
||||
continue;
|
||||
}
|
||||
pCLServing->iState = S_HALT1;
|
||||
FileWrite(pCLServing->fd, "halt ", -1);
|
||||
break;
|
||||
@ -2961,8 +3057,8 @@ DoClientRead(pGE, pCLServing)
|
||||
pCLServing->fwr = 0;
|
||||
TagLogfileAct(pCEServing, "%s detached",
|
||||
pCLServing->acid->string);
|
||||
pCEServing->pCLwr =
|
||||
FindWrite(pCEServing->pCLon);
|
||||
pCEServing->pCLwr = (CONSCLIENT *)0;
|
||||
FindWrite(pCEServing);
|
||||
FileWrite(pCLServing->fd, "spying]\r\n", -1);
|
||||
break;
|
||||
|
||||
@ -3013,7 +3109,17 @@ DoClientRead(pGE, pCLServing)
|
||||
break;
|
||||
|
||||
case '\t': /* toggle tab expand */
|
||||
FileWrite(pCLServing->fd, "tabs]\r\n", -1);
|
||||
if (!pCLServing->fwr) {
|
||||
FileWrite(pCLServing->fd,
|
||||
"attach to toggle tabs]\r\n",
|
||||
-1);
|
||||
continue;
|
||||
}
|
||||
if (pCEServing->type != DEVICE &&
|
||||
pCEServing->type != EXEC) {
|
||||
FileWrite(pCLServing->fd, "ok]\r\n", -1);
|
||||
continue;
|
||||
}
|
||||
if (-1 ==
|
||||
tcgetattr(FileFDNum(pCEServing->cofile),
|
||||
&sbuf)) {
|
||||
@ -3038,6 +3144,12 @@ DoClientRead(pGE, pCLServing)
|
||||
-1);
|
||||
continue;
|
||||
}
|
||||
if (XTABS == (TABDLY & sbuf.c_oflag))
|
||||
FileWrite(pCLServing->fd, "tabs OFF]\r\n",
|
||||
-1);
|
||||
else
|
||||
FileWrite(pCLServing->fd, "tabs ON]\r\n",
|
||||
-1);
|
||||
break;
|
||||
|
||||
case 'Q': /* DEC vt100 PF2 */
|
||||
@ -3047,24 +3159,23 @@ DoClientRead(pGE, pCLServing)
|
||||
FileWrite(pCLServing->fd, "disconnect]\r\n",
|
||||
-1);
|
||||
nr = 0;
|
||||
if (!pCEServing->fup ||
|
||||
pCEServing->type != DEVICE) {
|
||||
DisconnectClient(pGE, pCLServing,
|
||||
(char *)0, FLAGFALSE);
|
||||
continue;
|
||||
}
|
||||
if (pCEServing->fup &&
|
||||
pCEServing->type == DEVICE) {
|
||||
if (-1 ==
|
||||
tcgetattr(FileFDNum(pCEServing->cofile),
|
||||
tcgetattr(FileFDNum
|
||||
(pCEServing->cofile),
|
||||
&sbuf)) {
|
||||
FileWrite(pCLServing->fd, "[failed]\r\n",
|
||||
-1);
|
||||
FileWrite(pCLServing->fd,
|
||||
"[failed]\r\n", -1);
|
||||
continue;
|
||||
}
|
||||
if (0 == (sbuf.c_iflag & IXOFF)) {
|
||||
sbuf.c_iflag |= IXOFF | IXON;
|
||||
tcsetattr(FileFDNum(pCEServing->cofile),
|
||||
tcsetattr(FileFDNum
|
||||
(pCEServing->cofile),
|
||||
TCSANOW, &sbuf);
|
||||
}
|
||||
}
|
||||
DisconnectClient(pGE, pCLServing, (char *)0,
|
||||
FLAGFALSE);
|
||||
continue;
|
||||
@ -3078,7 +3189,7 @@ DoClientRead(pGE, pCLServing)
|
||||
case '\\': /* quote mode (send ^Q,^S) */
|
||||
if (pCEServing->fronly) {
|
||||
FileWrite(pCLServing->fd,
|
||||
"can't write to read-only host]\r\n",
|
||||
"can't write to read-only console]\r\n",
|
||||
-1);
|
||||
continue;
|
||||
}
|
||||
@ -3404,11 +3515,14 @@ Kiddie(pGE, sfd)
|
||||
break;
|
||||
}
|
||||
pCEServing->ioState = ISNORMAL;
|
||||
StartInit(pCEServing);
|
||||
}
|
||||
break;
|
||||
case ISNORMAL:
|
||||
if (FileCanRead(pCEServing->cofile, &rmask, &wmask))
|
||||
DoConsoleRead(pCEServing);
|
||||
if (FileCanRead(pCEServing->initfile, &rmask, &wmask))
|
||||
DoCommandRead(pCEServing);
|
||||
/* fall through to ISFLUSHING for buffered data */
|
||||
case ISFLUSHING:
|
||||
/* write cofile data */
|
||||
@ -3432,10 +3546,23 @@ Kiddie(pGE, sfd)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* write initfile data */
|
||||
if (!FileBufEmpty(pCEServing->initfile) &&
|
||||
FileCanWrite(pCEServing->initfile, &rmask,
|
||||
&wmask)) {
|
||||
CONDDEBUG((1, "Kiddie(): flushing fd %d",
|
||||
FileFDNum(pCEServing->initfile)));
|
||||
if (FileWrite(pCEServing->initfile, (char *)0, 0) <
|
||||
0) {
|
||||
ConsoleError(pCEServing);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* stop if we're in ISFLUSHING state and out of data */
|
||||
if ((pCEServing->ioState == ISFLUSHING) &&
|
||||
FileBufEmpty(pCEServing->cofile) &&
|
||||
FileBufEmpty(pCEServing->fdlog))
|
||||
FileBufEmpty(pCEServing->fdlog) &&
|
||||
FileBufEmpty(pCEServing->initfile))
|
||||
/* no ConsoleError() for same reason as above */
|
||||
ConsDown(pCEServing, FLAGFALSE, FLAGTRUE);
|
||||
break;
|
||||
@ -3508,7 +3635,7 @@ Kiddie(pGE, sfd)
|
||||
int justHadDelay = 0;
|
||||
if (pCEServing->wbuf->used <= 1)
|
||||
continue;
|
||||
if (!pCEServing->fup) {
|
||||
if (!(pCEServing->fup && pCEServing->ioState == ISNORMAL)) {
|
||||
/* if we have data but aren't up, drop it */
|
||||
BuildString((char *)0, pCEServing->wbuf);
|
||||
pCEServing->wbufIAC = 0;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: main.c,v 5.157 2003-09-22 08:33:58-07 bryan Exp $
|
||||
* $Id: main.c,v 5.160 2003-09-29 07:01:35-07 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -67,6 +67,10 @@ char *interface = (char *)0;
|
||||
|
||||
struct sockaddr_in in_port;
|
||||
|
||||
#if HAVE_DMALLOC && DMALLOC_MARK_MAIN
|
||||
unsigned long dmallocMarkMain = 0;
|
||||
#endif
|
||||
|
||||
#if HAVE_OPENSSL
|
||||
SSL_CTX *ctx = (SSL_CTX *)0;
|
||||
DH *dh512 = (DH *)0;
|
||||
@ -473,7 +477,7 @@ Usage(wantfull)
|
||||
static char u_terse[] =
|
||||
"[-7dDEFhinoRSuvV] [-a type] [-m max] [-M addr] [-p port] [-b port] [-c cred] [-C config] [-P passwd] [-L logfile] [-O min]";
|
||||
static char *full[] = {
|
||||
"7 strip the high bit of all console data",
|
||||
"7 strip the high bit off all console data",
|
||||
"a type set the default access type",
|
||||
"b port base port for secondary channel (any by default)",
|
||||
#if HAVE_OPENSSL
|
||||
@ -696,12 +700,16 @@ SummarizeDataStructures()
|
||||
size += strlen(pCE->master);
|
||||
if (pCE->logfile != (char *)0)
|
||||
size += strlen(pCE->logfile);
|
||||
if (pCE->initcmd != (char *)0)
|
||||
size += strlen(pCE->initcmd);
|
||||
if (pCE->execSlave != (char *)0)
|
||||
size += strlen(pCE->execSlave);
|
||||
if (pCE->fdlog != (CONSFILE *)0)
|
||||
size += sizeof(CONSFILE);
|
||||
if (pCE->cofile != (CONSFILE *)0)
|
||||
size += sizeof(CONSFILE);
|
||||
if (pCE->initfile != (CONSFILE *)0)
|
||||
size += sizeof(CONSFILE);
|
||||
if (pCE->aliases != (NAMES *)0) {
|
||||
NAMES *n;
|
||||
for (n = pCE->aliases; n != (NAMES *)0; n = n->next) {
|
||||
@ -776,6 +784,10 @@ DumpDataStructures()
|
||||
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
|
||||
if (!fDebug)
|
||||
return;
|
||||
@ -864,6 +876,10 @@ DumpDataStructures()
|
||||
pCE->reinitoncc == FLAGTRUE ? "true" : "false",
|
||||
pCE->striphigh == FLAGTRUE ? "true" : "false",
|
||||
pCE->unloved == FLAGTRUE ? "true" : "false"));
|
||||
CONDDEBUG((1,
|
||||
"DumpDataStructures(): initpid=%lu, initcmd=%s, initfile=%d",
|
||||
(unsigned long)pCE->initpid, EMPTYSTR(pCE->initcmd),
|
||||
FileFDNum(pCE->initfile)));
|
||||
if (pCE->ro) {
|
||||
CONSENTUSERS *u;
|
||||
for (u = pCE->ro; u != (CONSENTUSERS *)0; u = u->next) {
|
||||
@ -912,6 +928,20 @@ ProbeInterfaces()
|
||||
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);
|
||||
@ -1011,6 +1041,20 @@ ProbeInterfaces()
|
||||
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,
|
||||
@ -1028,23 +1072,11 @@ ProbeInterfaces()
|
||||
if (myAddrs != (struct in_addr *)0)
|
||||
free(myAddrs);
|
||||
myAddrs = (struct in_addr *)0;
|
||||
if (bindAddr != INADDR_ANY)
|
||||
count++;
|
||||
if (count == 0)
|
||||
return;
|
||||
myAddrs = (struct in_addr *)calloc(count + 1, sizeof(struct in_addr));
|
||||
if (myAddrs == (struct in_addr *)0)
|
||||
OutOfMem();
|
||||
if (bindAddr != INADDR_ANY) {
|
||||
count--;
|
||||
#if HAVE_MEMCPY
|
||||
memcpy(&(myAddrs[count].s_addr), &bindAddr, sizeof(in_addr_t));
|
||||
#else
|
||||
bcopy(&bindAddr, &(myAddrs[count].s_addr), sizeof(in_addr_t));
|
||||
#endif
|
||||
Verbose("interface address %s (-M option)",
|
||||
inet_ntoa(myAddrs[count]));
|
||||
}
|
||||
for (count--; count >= 0; count--) {
|
||||
#if HAVE_MEMCPY
|
||||
memcpy(&(myAddrs[count].s_addr), he->h_addr_list[count],
|
||||
@ -1439,6 +1471,10 @@ main(argc, argv)
|
||||
config->sslcredentials = (char *)0;
|
||||
#endif
|
||||
|
||||
#if HAVE_DMALLOC && DMALLOC_MARK_MAIN
|
||||
dmallocMarkMain = dmalloc_mark();
|
||||
#endif
|
||||
|
||||
if (pGroups == (GRPENT *)0 && pRCList == (REMOTE *)0) {
|
||||
Error("no consoles found in configuration file");
|
||||
} else if (!fSyntaxOnly) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: master.c,v 5.113 2003-09-19 08:58:18-07 bryan Exp $
|
||||
* $Id: master.c,v 5.115 2003-09-29 08:39:13-07 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -76,13 +76,15 @@ FixKids()
|
||||
int UWbuf;
|
||||
GRPENT *pGE;
|
||||
|
||||
while (-1 != (pid = waitpid(-1, &UWbuf, WNOHANG))) {
|
||||
while (-1 != (pid = waitpid(-1, &UWbuf, WNOHANG | WUNTRACED))) {
|
||||
if (0 == pid) {
|
||||
break;
|
||||
}
|
||||
/* stopped child is just continuted
|
||||
*/
|
||||
if (WIFSTOPPED(UWbuf) && 0 == kill(pid, SIGCONT)) {
|
||||
Msg("child pid %lu: stopped, sending SIGCONT",
|
||||
(unsigned long)pid);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -258,6 +260,17 @@ CommandCall(pCL, args)
|
||||
++found;
|
||||
}
|
||||
}
|
||||
if (config->redirect == FLAGTRUE ||
|
||||
(config->redirect != FLAGTRUE && found == 0)) {
|
||||
for (pRC = pRCList; (REMOTE *)0 != pRC; pRC = pRC->pRCnext) {
|
||||
if (strcasecmp(args, pRC->rserver) != 0)
|
||||
continue;
|
||||
ambiguous = BuildTmpString(pRC->rserver);
|
||||
ambiguous = BuildTmpString(", ");
|
||||
++found;
|
||||
pRCFound = pRC;
|
||||
}
|
||||
}
|
||||
if (found == 0) { /* Then look for substring matches */
|
||||
NAMES *name = (NAMES *)0;
|
||||
int foundOne = 0;
|
||||
@ -512,7 +525,8 @@ DoNormalRead(pCLServing)
|
||||
pCLServing->acid->string);
|
||||
FileWrite(pCLServing->fd, "ok\r\n", -1);
|
||||
} else {
|
||||
FileWrite(pCLServing->fd, "passwd?\r\n", -1);
|
||||
FilePrint(pCLServing->fd, "passwd? %s\r\n",
|
||||
myHostname);
|
||||
pCLServing->iState = S_PASSWD;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: readcfg.c,v 5.137 2003-08-21 15:03:25-07 bryan Exp $
|
||||
* $Id: readcfg.c,v 5.140 2003-09-28 09:32:55-07 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -26,8 +26,8 @@
|
||||
#include <compat.h>
|
||||
|
||||
#include <util.h>
|
||||
#include <client.h>
|
||||
#include <consent.h>
|
||||
#include <client.h>
|
||||
#include <group.h>
|
||||
#include <access.h>
|
||||
#include <readcfg.h>
|
||||
@ -623,6 +623,8 @@ DestroyParserDefaultOrConsole(c, ph, pt)
|
||||
free(c->device);
|
||||
if (c->logfile != (char *)0)
|
||||
free(c->logfile);
|
||||
if (c->initcmd != (char *)0)
|
||||
free(c->initcmd);
|
||||
if (c->execSlave != (char *)0)
|
||||
free(c->execSlave);
|
||||
if (c->wbuf != (STRING *)0)
|
||||
@ -727,6 +729,12 @@ ApplyDefault(d, c)
|
||||
if ((c->logfile = strdup(d->logfile)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
if (d->initcmd != (char *)0) {
|
||||
if (c->initcmd != (char *)0)
|
||||
free(c->initcmd);
|
||||
if ((c->initcmd = strdup(d->initcmd)) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
if (d->ro != (CONSENTUSERS *)0) {
|
||||
CONSENTUSERS *u;
|
||||
for (u = d->ro; u != (CONSENTUSERS *)0; u = u->next) {
|
||||
@ -1071,6 +1079,27 @@ ProcessLogfile(c, id)
|
||||
OutOfMem();
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ProcessRuninit(CONSENT *c, char *id)
|
||||
#else
|
||||
ProcessRuninit(c, id)
|
||||
CONSENT *c;
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
if (c->initcmd != (char *)0) {
|
||||
free(c->initcmd);
|
||||
c->initcmd = (char *)0;
|
||||
}
|
||||
if (id == (char *)0 || id[0] == '\000') {
|
||||
return;
|
||||
}
|
||||
if ((c->initcmd = strdup(id))
|
||||
== (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
DefaultItemLogfile(char *id)
|
||||
@ -1083,6 +1112,18 @@ DefaultItemLogfile(id)
|
||||
ProcessLogfile(parserDefaultTemp, id);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
DefaultItemRuninit(char *id)
|
||||
#else
|
||||
DefaultItemRuninit(id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "DefaultItemRuninit(%s) [%s:%d]", id, file, line));
|
||||
ProcessRuninit(parserDefaultTemp, id);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ProcessMaster(CONSENT *c, char *id)
|
||||
@ -1945,6 +1986,14 @@ ConsoleAdd(c)
|
||||
if (!FileBufEmpty(pCEmatch->cofile))
|
||||
FD_SET(cofile, &winit);
|
||||
}
|
||||
if (pCEmatch->initfile != (CONSFILE *)0) {
|
||||
int initfile = FileFDNum(pCEmatch->initfile);
|
||||
FD_SET(initfile, &rinit);
|
||||
if (maxfd < initfile + 1)
|
||||
maxfd = initfile + 1;
|
||||
if (!FileBufEmpty(pCEmatch->initfile))
|
||||
FD_SET(FileFDOutNum(pCEmatch->initfile), &winit);
|
||||
}
|
||||
|
||||
/* now check for any changes between pCEmatch & c.
|
||||
* we can munch the pCEmatch structure 'cause ConsDown()
|
||||
@ -1964,6 +2013,20 @@ ConsoleAdd(c)
|
||||
SwapStr(pCEmatch->logfile, c->logfile);
|
||||
closeMatch = 0;
|
||||
}
|
||||
if (pCEmatch->initcmd != (char *)0 && c->initcmd != (char *)0) {
|
||||
if (strcmp(pCEmatch->initcmd, c->initcmd) != 0) {
|
||||
SwapStr(pCEmatch->initcmd, c->initcmd);
|
||||
/* only trigger reinit if we're running the old command */
|
||||
if (pCEmatch->initpid != 0)
|
||||
closeMatch = 0;
|
||||
}
|
||||
} else if (pCEmatch->initcmd != (char *)0 ||
|
||||
c->initcmd != (char *)0) {
|
||||
SwapStr(pCEmatch->initcmd, c->initcmd);
|
||||
/* only trigger reinit if we're running the old command */
|
||||
if (pCEmatch->initpid != 0)
|
||||
closeMatch = 0;
|
||||
}
|
||||
|
||||
switch (pCEmatch->type) {
|
||||
case EXEC:
|
||||
@ -2266,7 +2329,8 @@ ConsoleDestroy()
|
||||
TagLogfile(pCE,
|
||||
"Console logging restored (bumped)");
|
||||
}
|
||||
pCE->pCLwr = FindWrite(pCE->pCLon);
|
||||
pCE->pCLwr = (CONSCLIENT *)0;
|
||||
FindWrite(pCE);
|
||||
}
|
||||
} else {
|
||||
FileWrite(pCL->fd,
|
||||
@ -2442,6 +2506,18 @@ ConsoleItemLogfile(id)
|
||||
ProcessLogfile(parserConsoleTemp, id);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ConsoleItemRuninit(char *id)
|
||||
#else
|
||||
ConsoleItemRuninit(id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
CONDDEBUG((1, "ConsoleItemRuninit(%s) [%s:%d]", id, file, line));
|
||||
ProcessRuninit(parserConsoleTemp, id);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ConsoleItemMaster(char *id)
|
||||
@ -2844,8 +2920,6 @@ AccessProcessACL(trust, acl)
|
||||
#endif
|
||||
{
|
||||
char *token = (char *)0;
|
||||
int i = 0, isCIDR = 0;
|
||||
int nCount = 0, dCount = 0, sCount = 0, mCount = 0, sPos = 0;
|
||||
ACCESS **ppa = (ACCESS **)0;
|
||||
ACCESS *pa = (ACCESS *)0;
|
||||
in_addr_t addr;
|
||||
@ -2872,6 +2946,8 @@ AccessProcessACL(trust, acl)
|
||||
|
||||
for (token = strtok(acl, ALLWORDSEP); token != (char *)0;
|
||||
token = strtok(NULL, ALLWORDSEP)) {
|
||||
int i = 0, isCIDR = 0;
|
||||
int nCount = 0, dCount = 0, sCount = 0, mCount = 0, sPos = 0;
|
||||
/* Scan for [0-9./], and stop if you find something else */
|
||||
for (i = 0; token[i] != '\000'; i++) {
|
||||
if (isdigit((int)(token[i]))) {
|
||||
@ -3000,6 +3076,8 @@ DestroyConfig(c)
|
||||
return;
|
||||
if (c->logfile != (char *)0)
|
||||
free(c->logfile);
|
||||
if (c->initcmd != (char *)0)
|
||||
free(c->initcmd);
|
||||
if (c->passwdfile != (char *)0)
|
||||
free(c->passwdfile);
|
||||
if (c->primaryport != (char *)0)
|
||||
@ -3059,6 +3137,12 @@ ConfigEnd()
|
||||
pConfig->logfile = parserConfigTemp->logfile;
|
||||
parserConfigTemp->logfile = (char *)0;
|
||||
}
|
||||
if (parserConfigTemp->initcmd != (char *)0) {
|
||||
if (pConfig->initcmd != (char *)0)
|
||||
free(pConfig->initcmd);
|
||||
pConfig->initcmd = parserConfigTemp->initcmd;
|
||||
parserConfigTemp->initcmd = (char *)0;
|
||||
}
|
||||
if (parserConfigTemp->passwdfile != (char *)0) {
|
||||
if (pConfig->passwdfile != (char *)0)
|
||||
free(pConfig->passwdfile);
|
||||
@ -3377,6 +3461,7 @@ ITEM keyDefault[] = {
|
||||
{"parity", DefaultItemParity},
|
||||
{"port", DefaultItemPort},
|
||||
{"ro", DefaultItemRo},
|
||||
{"initcmd", DefaultItemRuninit},
|
||||
{"rw", DefaultItemRw},
|
||||
{"timestamp", DefaultItemTimestamp},
|
||||
{"type", DefaultItemType},
|
||||
@ -3398,6 +3483,7 @@ ITEM keyConsole[] = {
|
||||
{"parity", ConsoleItemParity},
|
||||
{"port", ConsoleItemPort},
|
||||
{"ro", ConsoleItemRo},
|
||||
{"initcmd", ConsoleItemRuninit},
|
||||
{"rw", ConsoleItemRw},
|
||||
{"timestamp", ConsoleItemTimestamp},
|
||||
{"type", ConsoleItemType},
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: readcfg.h,v 5.31 2003-08-21 15:02:16-07 bryan Exp $
|
||||
* $Id: readcfg.h,v 5.32 2003-09-28 08:54:16-07 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -11,6 +11,7 @@ typedef struct config {
|
||||
char defaultaccess;
|
||||
FLAG daemonmode;
|
||||
char *logfile;
|
||||
char *initcmd;
|
||||
char *passwdfile;
|
||||
char *primaryport;
|
||||
FLAG redirect;
|
||||
|
120
conserver/util.c
120
conserver/util.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: util.c,v 1.98 2003-08-24 10:40:10-07 bryan Exp $
|
||||
* $Id: util.c,v 1.99 2003-09-28 08:51:52-07 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -75,12 +75,12 @@ StrTime(ltime)
|
||||
time_t *ltime;
|
||||
#endif
|
||||
{
|
||||
static char curtime[25];
|
||||
static char curtime[40]; /* just in case ctime() varies */
|
||||
time_t tyme;
|
||||
|
||||
tyme = time((time_t *)0);
|
||||
strcpy(curtime, ctime(&tyme));
|
||||
curtime[24] = '\000';
|
||||
curtime[24] = '\000'; /* might need to adjust this at some point */
|
||||
if (ltime != NULL)
|
||||
*ltime = tyme;
|
||||
return (const char *)curtime;
|
||||
@ -730,6 +730,37 @@ FileOpenFD(fd, type)
|
||||
return cfp;
|
||||
}
|
||||
|
||||
/* This encapsulates a pipe pair in a CONSFILE
|
||||
* object. Returns a CONSFILE pointer to that object.
|
||||
*/
|
||||
CONSFILE *
|
||||
#if PROTOTYPES
|
||||
FileOpenPipe(int fd, int fdout)
|
||||
#else
|
||||
FileOpenPipe(fd, fdout)
|
||||
int fd;
|
||||
int fdout;
|
||||
#endif
|
||||
{
|
||||
CONSFILE *cfp;
|
||||
|
||||
if ((cfp = (CONSFILE *)calloc(1, sizeof(CONSFILE)))
|
||||
== (CONSFILE *)0)
|
||||
OutOfMem();
|
||||
cfp->ftype = simplePipe;
|
||||
cfp->fd = fd;
|
||||
cfp->fdout = fdout;
|
||||
cfp->wbuf = AllocString();
|
||||
#if HAVE_OPENSSL
|
||||
cfp->ssl = (SSL *)0;
|
||||
cfp->waitForRead = cfp->waitForWrite = FLAGFALSE;
|
||||
#endif
|
||||
|
||||
CONDDEBUG((2, "FileOpenPipe(): encapsulated pipe pair fd %d and fd %d",
|
||||
fd, fdout));
|
||||
return cfp;
|
||||
}
|
||||
|
||||
/* This is to "unencapsulate" the file descriptor */
|
||||
int
|
||||
#if PROTOTYPES
|
||||
@ -745,6 +776,9 @@ FileUnopen(cfp)
|
||||
case simpleFile:
|
||||
retval = cfp->fd;
|
||||
break;
|
||||
case simplePipe:
|
||||
retval = cfp->fd;
|
||||
break;
|
||||
case simpleSocket:
|
||||
retval = cfp->fd;
|
||||
break;
|
||||
@ -758,6 +792,7 @@ FileUnopen(cfp)
|
||||
break;
|
||||
}
|
||||
CONDDEBUG((2, "FileUnopen(): unopened fd %d", cfp->fd));
|
||||
DestroyString(cfp->wbuf);
|
||||
free(cfp);
|
||||
|
||||
return retval;
|
||||
@ -826,6 +861,14 @@ FileClose(pcfp)
|
||||
retval = close(cfp->fd);
|
||||
} while (retval == -1 && errno == EINTR);
|
||||
break;
|
||||
case simplePipe:
|
||||
do {
|
||||
retval = close(cfp->fd);
|
||||
} while (retval == -1 && errno == EINTR);
|
||||
do {
|
||||
retval = close(cfp->fdout);
|
||||
} while (retval == -1 && errno == EINTR);
|
||||
break;
|
||||
case simpleSocket:
|
||||
#if defined(__CYGWIN__)
|
||||
/* flush out the client socket - set it to blocking,
|
||||
@ -896,6 +939,7 @@ FileRead(cfp, buf, len)
|
||||
|
||||
switch (cfp->ftype) {
|
||||
case simpleFile:
|
||||
case simplePipe:
|
||||
case simpleSocket:
|
||||
while (retval < 0) {
|
||||
if ((retval = read(cfp->fd, buf, len)) <= 0) {
|
||||
@ -994,10 +1038,16 @@ FileWrite(cfp, buf, len)
|
||||
int len_orig = len;
|
||||
int len_out = 0;
|
||||
int retval = 0;
|
||||
int fdout = 0;
|
||||
|
||||
if (len < 0 && buf != (char *)0)
|
||||
len = strlen(buf);
|
||||
|
||||
if (cfp->ftype == simplePipe)
|
||||
fdout = cfp->fdout;
|
||||
else
|
||||
fdout = cfp->fd;
|
||||
|
||||
if (fDebug && len > 0 && buf != (char *)0) {
|
||||
static STRING *tmpString = (STRING *)0;
|
||||
if (tmpString == (STRING *)0)
|
||||
@ -1005,7 +1055,7 @@ FileWrite(cfp, buf, len)
|
||||
BuildString((char *)0, tmpString);
|
||||
FmtCtlStr(buf, len > 30 ? 30 : len, tmpString);
|
||||
CONDDEBUG((2, "FileWrite(): sending `%s' to fd %d",
|
||||
tmpString->string, cfp->fd));
|
||||
tmpString->string, fdout));
|
||||
}
|
||||
/* save the data */
|
||||
if (len > 0 && buf != (char *)0)
|
||||
@ -1024,10 +1074,11 @@ FileWrite(cfp, buf, len)
|
||||
* stop when we hit an error or flush all the data.
|
||||
*/
|
||||
switch (cfp->ftype) {
|
||||
case simplePipe:
|
||||
case simpleFile:
|
||||
case simpleSocket:
|
||||
while (len > 0) {
|
||||
if ((retval = write(cfp->fd, buf, len)) < 0) {
|
||||
if ((retval = write(fdout, buf, len)) < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
if (errno == EAGAIN) {
|
||||
@ -1038,7 +1089,7 @@ FileWrite(cfp, buf, len)
|
||||
retval = -1;
|
||||
if (errno == EPIPE)
|
||||
break;
|
||||
Error("FileWrite(): fd %d: %s", cfp->fd,
|
||||
Error("FileWrite(): fd %d: %s", fdout,
|
||||
strerror(errno));
|
||||
break;
|
||||
}
|
||||
@ -1110,20 +1161,20 @@ FileWrite(cfp, buf, len)
|
||||
}
|
||||
}
|
||||
if (cfp->wbuf->used <= 1)
|
||||
FD_CLR(cfp->fd, &winit);
|
||||
FD_CLR(fdout, &winit);
|
||||
else {
|
||||
FD_SET(cfp->fd, &winit);
|
||||
FD_SET(fdout, &winit);
|
||||
CONDDEBUG((2, "FileWrite(): buffered %d byte%s for fd %d",
|
||||
(cfp->wbuf->used <= 1) ? 0 : cfp->wbuf->used,
|
||||
(cfp->wbuf->used <= 1) ? "" : "s", cfp->fd));
|
||||
(cfp->wbuf->used <= 1) ? "" : "s", fdout));
|
||||
}
|
||||
|
||||
if (len_out >= 0) {
|
||||
CONDDEBUG((2, "FileWrite(): wrote %d byte%s to fd %d", len_out,
|
||||
(len_out == 1) ? "" : "s", cfp->fd));
|
||||
(len_out == 1) ? "" : "s", fdout));
|
||||
} else {
|
||||
CONDDEBUG((2, "FileWrite(): write of %d byte%s to fd %d: %s",
|
||||
len_orig, (len_out == -1) ? "" : "s", cfp->fd,
|
||||
len_orig, (len_out == -1) ? "" : "s", fdout,
|
||||
strerror(errno)));
|
||||
}
|
||||
return len_out;
|
||||
@ -1139,12 +1190,19 @@ FileCanRead(cfp, prfd, pwfd)
|
||||
fd_set *pwfd;
|
||||
#endif
|
||||
{
|
||||
int fdout;
|
||||
|
||||
if (cfp == (CONSFILE *)0)
|
||||
return 0;
|
||||
|
||||
if (cfp->ftype == simplePipe)
|
||||
fdout = cfp->fdout;
|
||||
else
|
||||
fdout = cfp->fd;
|
||||
|
||||
return ((FD_ISSET(cfp->fd, prfd)
|
||||
#if HAVE_OPENSSL
|
||||
&& cfp->waitForRead != FLAGTRUE) || (FD_ISSET(cfp->fd, pwfd)
|
||||
&& cfp->waitForRead != FLAGTRUE) || (FD_ISSET(fdout, pwfd)
|
||||
&& cfp->waitForWrite ==
|
||||
FLAGTRUE
|
||||
#endif
|
||||
@ -1161,10 +1219,17 @@ FileCanWrite(cfp, prfd, pwfd)
|
||||
fd_set *pwfd;
|
||||
#endif
|
||||
{
|
||||
int fdout;
|
||||
|
||||
if (cfp == (CONSFILE *)0)
|
||||
return 0;
|
||||
|
||||
return ((FD_ISSET(cfp->fd, pwfd)
|
||||
if (cfp->ftype == simplePipe)
|
||||
fdout = cfp->fdout;
|
||||
else
|
||||
fdout = cfp->fd;
|
||||
|
||||
return ((FD_ISSET(fdout, pwfd)
|
||||
#if HAVE_OPENSSL
|
||||
&& cfp->waitForWrite != FLAGTRUE) || (FD_ISSET(cfp->fd, prfd)
|
||||
&& cfp->waitForRead ==
|
||||
@ -1399,6 +1464,9 @@ FileStat(cfp, buf)
|
||||
case simpleFile:
|
||||
retval = fstat(cfp->fd, buf);
|
||||
break;
|
||||
case simplePipe:
|
||||
retval = -1;
|
||||
break;
|
||||
case simpleSocket:
|
||||
retval = fstat(cfp->fd, buf);
|
||||
break;
|
||||
@ -1432,6 +1500,9 @@ FileSeek(cfp, offset, whence)
|
||||
case simpleFile:
|
||||
retval = lseek(cfp->fd, offset, whence);
|
||||
break;
|
||||
case simplePipe:
|
||||
retval = -1;
|
||||
break;
|
||||
case simpleSocket:
|
||||
retval = lseek(cfp->fd, offset, whence);
|
||||
break;
|
||||
@ -1466,6 +1537,9 @@ FileFDNum(cfp)
|
||||
case simpleFile:
|
||||
retval = cfp->fd;
|
||||
break;
|
||||
case simplePipe:
|
||||
retval = cfp->fd;
|
||||
break;
|
||||
case simpleSocket:
|
||||
retval = cfp->fd;
|
||||
break;
|
||||
@ -1482,6 +1556,21 @@ FileFDNum(cfp)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Returns the file descriptor number of the underlying file */
|
||||
int
|
||||
#if PROTOTYPES
|
||||
FileFDOutNum(CONSFILE *cfp)
|
||||
#else
|
||||
FileFDOutNum(cfp)
|
||||
CONSFILE *cfp;
|
||||
#endif
|
||||
{
|
||||
if (cfp == (CONSFILE *)0 || cfp->ftype != simplePipe)
|
||||
return -1;
|
||||
|
||||
return cfp->fdout;
|
||||
}
|
||||
|
||||
/* Returns the file type */
|
||||
enum consFileType
|
||||
#if PROTOTYPES
|
||||
@ -1494,6 +1583,8 @@ FileGetType(cfp)
|
||||
switch (cfp->ftype) {
|
||||
case simpleFile:
|
||||
return simpleFile;
|
||||
case simplePipe:
|
||||
return simplePipe;
|
||||
case simpleSocket:
|
||||
return simpleSocket;
|
||||
#if HAVE_OPENSSL
|
||||
@ -1629,6 +1720,9 @@ FileSend(cfp, msg, len, flags)
|
||||
case simpleFile:
|
||||
retval = send(cfp->fd, msg, len, flags);
|
||||
break;
|
||||
case simplePipe:
|
||||
retval = send(cfp->fdout, msg, len, flags);
|
||||
break;
|
||||
case simpleSocket:
|
||||
retval = send(cfp->fd, msg, len, flags);
|
||||
break;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: util.h,v 1.52 2003-08-23 11:06:35-07 bryan Exp $
|
||||
* $Id: util.h,v 1.53 2003-09-28 08:45:31-07 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -28,6 +28,7 @@
|
||||
enum consFileType {
|
||||
simpleFile,
|
||||
simpleSocket,
|
||||
simplePipe,
|
||||
#if HAVE_OPENSSL
|
||||
SSLSocket,
|
||||
#endif
|
||||
@ -64,6 +65,7 @@ typedef struct consFile {
|
||||
/* Standard socket type stuff */
|
||||
enum consFileType ftype;
|
||||
int fd;
|
||||
int fdout; /* only used when a simplePipe */
|
||||
STRING *wbuf;
|
||||
#if HAVE_OPENSSL
|
||||
/* SSL stuff */
|
||||
@ -96,6 +98,7 @@ extern int GetMaxFiles PARAMS(());
|
||||
extern char *FmtCtl PARAMS((int, STRING *));
|
||||
extern void FmtCtlStr PARAMS((char *, int, STRING *));
|
||||
extern CONSFILE *FileOpenFD PARAMS((int, enum consFileType));
|
||||
extern CONSFILE *FileOpenPipe PARAMS((int, int));
|
||||
extern CONSFILE *FileOpen PARAMS((const char *, int, int));
|
||||
extern int FileClose PARAMS((CONSFILE **));
|
||||
extern int FileRead PARAMS((CONSFILE *, void *, int));
|
||||
@ -106,6 +109,7 @@ extern int FileStat PARAMS((CONSFILE *, struct stat *));
|
||||
extern int FileSeek PARAMS((CONSFILE *, off_t, int));
|
||||
extern int FileSend PARAMS((CONSFILE *, const void *, size_t, int));
|
||||
extern int FileFDNum PARAMS((CONSFILE *));
|
||||
extern int FileFDOutNum PARAMS((CONSFILE *));
|
||||
extern int FileUnopen PARAMS((CONSFILE *));
|
||||
extern void OutOfMem PARAMS(());
|
||||
extern char *BuildTmpString PARAMS((const char *));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: version.h,v 1.46 2003-09-22 10:41:28-07 bryan Exp $
|
||||
* $Id: version.h,v 1.47 2003-09-28 13:34:49-07 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -14,4 +14,4 @@
|
||||
@(#) Copyright 2000 conserver.com.\n\
|
||||
All rights reserved.\n"
|
||||
|
||||
#define THIS_VERSION "conserver.com version 8.0.0"
|
||||
#define THIS_VERSION "conserver.com version 8.0.1"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: console.c,v 5.137 2003-09-22 08:23:57-07 bryan Exp $
|
||||
* $Id: console.c,v 5.141 2003-09-29 08:36:06-07 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -71,26 +71,26 @@ SetupSSL()
|
||||
SSL_load_error_strings();
|
||||
if (!SSL_library_init()) {
|
||||
Error("SSL library initialization failed");
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
if ((ctx = SSL_CTX_new(SSLv23_method())) == (SSL_CTX *)0) {
|
||||
Error("Creating SSL context failed");
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
if (SSL_CTX_set_default_verify_paths(ctx) != 1) {
|
||||
Error("Could not load SSL default CA file and/or directory");
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
if (pcCredFile != (char *)0) {
|
||||
if (SSL_CTX_use_certificate_chain_file(ctx, pcCredFile) != 1) {
|
||||
Error("Could not load SSL certificate from '%s'",
|
||||
pcCredFile);
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
if (SSL_CTX_use_PrivateKey_file
|
||||
(ctx, pcCredFile, SSL_FILETYPE_PEM) != 1) {
|
||||
Error("Could not SSL private key from '%s'", pcCredFile);
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, SSLVerifyCallback);
|
||||
@ -104,7 +104,7 @@ SetupSSL()
|
||||
if (SSL_CTX_set_cipher_list(ctx, "ALL:!LOW:!EXP:!MD5:@STRENGTH") !=
|
||||
1) {
|
||||
Error("Setting SSL cipher list failed");
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -121,11 +121,11 @@ AttemptSSL(pcf)
|
||||
|
||||
if (ctx == (SSL_CTX *)0) {
|
||||
Error("WTF? The SSL context disappeared?!?!?");
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
if (!(ssl = SSL_new(ctx))) {
|
||||
Error("Couldn't create new SSL context");
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
FileSetSSL(pcf, ssl);
|
||||
SSL_set_fd(ssl, FileFDNum(pcf));
|
||||
@ -133,7 +133,7 @@ AttemptSSL(pcf)
|
||||
if (SSL_connect(ssl) <= 0) {
|
||||
Error("SSL negotiation failed");
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
FileSetType(pcf, SSLSocket);
|
||||
CONDDEBUG((1, "SSL Connection: %s :: %s", SSL_get_cipher_version(ssl),
|
||||
@ -141,15 +141,6 @@ AttemptSSL(pcf)
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
DestroyDataStructures(void)
|
||||
#else
|
||||
DestroyDataStructures()
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
/* output a control (or plain) character as a UNIX user would expect it (ksb)
|
||||
*/
|
||||
static void
|
||||
@ -189,7 +180,7 @@ Usage(wantfull)
|
||||
#endif
|
||||
{
|
||||
static char *full[] = {
|
||||
"7 strip the high bit of all console data",
|
||||
"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
|
||||
@ -206,8 +197,8 @@ Usage(wantfull)
|
||||
"E ignored - encryption not compiled into code",
|
||||
#endif
|
||||
"f(F) force read/write connection (and replay)",
|
||||
"i(I) display information in machine-parseable form (on master)",
|
||||
"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",
|
||||
@ -388,7 +379,7 @@ ValidateEsc()
|
||||
}
|
||||
if (c1 > 127 || c2 > 127) {
|
||||
Error("High-bit set in escape sequence: not allowed with -7");
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -408,12 +399,12 @@ ParseEsc(pcText)
|
||||
pcTemp = pcText;
|
||||
if (ParseChar(&pcTemp, &c1) || ParseChar(&pcTemp, &c2)) {
|
||||
Error("poorly formed escape sequence `%s\'", pcText);
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
if ('\000' != *pcTemp) {
|
||||
Error("too many characters in new escape sequence at ...`%s\'",
|
||||
pcTemp);
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
chAttn = c1;
|
||||
chEsc = c2;
|
||||
@ -521,7 +512,7 @@ C2Raw()
|
||||
|
||||
if (0 != tcgetattr(0, &o_tios)) {
|
||||
Error("tcgetattr(0): %s", strerror(errno));
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
n_tios = o_tios;
|
||||
n_tios.c_iflag &= ~(INLCR | IGNCR | ICRNL | IUCLC | IXON);
|
||||
@ -531,7 +522,7 @@ C2Raw()
|
||||
n_tios.c_cc[VTIME] = 0;
|
||||
if (0 != tcsetattr(0, TCSANOW, &n_tios)) {
|
||||
Error("tcsetattr(0, TCSANOW): %s", strerror(errno));
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
screwy = 1;
|
||||
}
|
||||
@ -552,6 +543,16 @@ C2Cooked()
|
||||
screwy = 0;
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
DestroyDataStructures(void)
|
||||
#else
|
||||
DestroyDataStructures()
|
||||
#endif
|
||||
{
|
||||
C2Cooked();
|
||||
}
|
||||
|
||||
char *
|
||||
#if PROTOTYPES
|
||||
ReadReply(CONSFILE *fd, int toEOF)
|
||||
@ -579,7 +580,7 @@ ReadReply(fd)
|
||||
break;
|
||||
C2Cooked();
|
||||
Error("lost connection");
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
default:
|
||||
BuildStringN(buf, nr, result);
|
||||
if (toEOF) /* if toEOF, read until EOF */
|
||||
@ -669,7 +670,7 @@ ProcessUrgentData(s)
|
||||
case OB_DROP:
|
||||
write(1, "dropped by server]\r\n", 20);
|
||||
C2Cooked();
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
/*NOTREACHED*/ default:
|
||||
Error("unknown out of band command `%c\'\r", acCmd);
|
||||
fflush(stderr);
|
||||
@ -735,14 +736,15 @@ CallUp(pcf, pcMaster, pcMach, pcHow, result)
|
||||
/* OK -- we are good as gold */
|
||||
fIn = 'a';
|
||||
} else if (0 == strcmp(result, "[spy]\r\n") ||
|
||||
0 == strcmp(result, "[ok]\r\n")) {
|
||||
0 == strcmp(result, "[ok]\r\n") ||
|
||||
0 == strcmp(result, "[read-only -- initializing]\r\n")) {
|
||||
/* Humph, someone else is on
|
||||
* or we have an old version of the server (4.X)
|
||||
*/
|
||||
fIn = 's';
|
||||
} else if (0 == strcmp(result, "[host is read-only]\r\n")) {
|
||||
} else if (0 == strcmp(result, "[console is read-only]\r\n")) {
|
||||
fIn = 'r';
|
||||
} else if (0 == strcmp(result, "[line to host is down]\r\n")) {
|
||||
} else if (0 == strcmp(result, "[line to console is down]\r\n")) {
|
||||
/* ouch, the machine is down on the server */
|
||||
fIn = '-';
|
||||
Error("%s is down", pcMach);
|
||||
@ -752,18 +754,9 @@ CallUp(pcf, pcMaster, pcMach, pcHow, result)
|
||||
PutCtlc(chEsc, stdout);
|
||||
printf("o\' to open console line]\n");
|
||||
}
|
||||
} else if (0 == strcmp(result, "[no -- on ctl]\r\n")) {
|
||||
fIn = '-';
|
||||
Error("%s is a control port", pcMach);
|
||||
if (fVerbose) {
|
||||
printf("[use `");
|
||||
PutCtlc(chAttn, stdout);
|
||||
PutCtlc(chEsc, stdout);
|
||||
printf(";\' to open a console line]\n");
|
||||
}
|
||||
} else {
|
||||
FilePrint(cfstdout, "%s: %s", pcMach, result);
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
|
||||
/* change escape sequence (if set on the command line)
|
||||
@ -783,7 +776,7 @@ CallUp(pcf, pcMaster, pcMach, pcHow, result)
|
||||
r = ReadReply(pcf, 0);
|
||||
if (strncmp(r, "[redef:", 7) != 0) {
|
||||
Error("protocol botch on redef of escape sequence");
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -974,15 +967,23 @@ DoCmds(master, ports, cmdi)
|
||||
FileWrite(pcf, t, -1);
|
||||
|
||||
t = ReadReply(pcf, 0);
|
||||
if (strcmp(t, "passwd?\r\n") == 0) {
|
||||
if (strncmp(t, "passwd?", 7) == 0) {
|
||||
static int count = 0;
|
||||
static STRING *tmpString = (STRING *)0;
|
||||
char *hostname = (char *)0;
|
||||
|
||||
if (t[7] == ' ') {
|
||||
hostname = PruneSpace(t + 7);
|
||||
if (*hostname == '\000')
|
||||
hostname = server;
|
||||
} else
|
||||
hostname = server;
|
||||
if (tmpString == (STRING *)0)
|
||||
tmpString = AllocString();
|
||||
if (tmpString->used <= 1) {
|
||||
char *pass;
|
||||
sprintf(acMesg, "Enter %s@%s's password: ", pcUser,
|
||||
master);
|
||||
hostname);
|
||||
pass = GetPassword(acMesg);
|
||||
if (pass == (char *)0) {
|
||||
Error("could not get password from tty for `%s'",
|
||||
@ -1036,7 +1037,7 @@ DoCmds(master, ports, cmdi)
|
||||
static int limit = 0;
|
||||
if (limit++ > 10) {
|
||||
Error("forwarding level too deep!");
|
||||
exit(EX_SOFTWARE);
|
||||
Bye(EX_SOFTWARE);
|
||||
}
|
||||
} else if (result[0] != '[') { /* did we not get a connection? */
|
||||
FilePrint(cfstdout, "%s: %s", server, result);
|
||||
@ -1260,11 +1261,11 @@ main(argc, argv)
|
||||
BuildString((char *)0, textMsg);
|
||||
if (optarg == (char *)0 || *optarg == '\000') {
|
||||
Error("no destination specified for -t", optarg);
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
} else if (strchr(optarg, ' ') != (char *)0) {
|
||||
Error("-t option cannot contain a space: `%s'",
|
||||
optarg);
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
BuildString("textmsg ", textMsg);
|
||||
BuildString(optarg, textMsg);
|
||||
@ -1296,21 +1297,21 @@ main(argc, argv)
|
||||
|
||||
case 'h': /* huh? */
|
||||
Usage(1);
|
||||
exit(EX_OK);
|
||||
Bye(EX_OK);
|
||||
|
||||
case '\?': /* huh? */
|
||||
Usage(0);
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
|
||||
default:
|
||||
Error("option %c needs a parameter", optopt);
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
if (fVersion) {
|
||||
Version();
|
||||
exit(EX_OK);
|
||||
Bye(EX_OK);
|
||||
}
|
||||
|
||||
/* finish resolving the command to do */
|
||||
@ -1321,20 +1322,20 @@ main(argc, argv)
|
||||
if (*pcCmd == 'a' || *pcCmd == 'f' || *pcCmd == 's') {
|
||||
if (optind >= argc) {
|
||||
Error("missing console name");
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
cmdarg = argv[optind++];
|
||||
} else if (*pcCmd == 't') {
|
||||
if (optind >= argc) {
|
||||
Error("missing message text");
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
cmdarg = argv[optind++];
|
||||
}
|
||||
|
||||
if (optind < argc) {
|
||||
Error("extra garbage on command line? (%s...)", argv[optind]);
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
|
||||
/* if we somehow lost the port (or got an empty string), reset */
|
||||
@ -1354,7 +1355,7 @@ main(argc, argv)
|
||||
struct servent *pSE;
|
||||
if ((pSE = getservbyname(pcPort, "tcp")) == (struct servent *)0) {
|
||||
Error("getservbyname(%s): %s", pcPort, strerror(errno));
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
} else {
|
||||
bindPort = ntohs((u_short) pSE->s_port);
|
||||
}
|
||||
@ -1367,13 +1368,13 @@ main(argc, argv)
|
||||
Error
|
||||
("$LOGNAME and $USER do not exist and getpwuid fails: %d: %s",
|
||||
(int)(getuid()), strerror(errno));
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
if (pcUser == (char *)0) {
|
||||
if (pwdMe->pw_name == (char *)0 || pwdMe->pw_name[0] == '\000') {
|
||||
Error("Username for uid %d does not exist",
|
||||
(int)(getuid()));
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
} else {
|
||||
pcUser = pwdMe->pw_name;
|
||||
}
|
||||
@ -1414,5 +1415,6 @@ main(argc, argv)
|
||||
if (*pcCmd == 'd')
|
||||
FilePrint(cfstdout, "Disconnected %d users\n", disconnectCount);
|
||||
|
||||
exit(retval);
|
||||
Bye(retval);
|
||||
return 0; /* noop - Bye() terminates us */
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" $Id: console.man,v 1.33 2003-09-22 08:21:31-07 bryan Exp $
|
||||
.TH CONSOLE 1 "2003-09-22" "conserver-8.0.0" "conserver"
|
||||
.\" $Id: console.man,v 1.36 2003-09-28 15:30:52-07 bryan Exp $
|
||||
.TH CONSOLE 1 "2003-09-28" "conserver-8.0.1" "conserver"
|
||||
.SH NAME
|
||||
console \- console server client program
|
||||
.SH SYNOPSIS
|
||||
@ -259,7 +259,7 @@ attached to
|
||||
.IR console ).
|
||||
.TP
|
||||
.B \-u
|
||||
Show a list of all consoles with status (`up' or `down')
|
||||
Show a list of all consoles with status (`up', `down', or `init')
|
||||
and attached users
|
||||
.RI ( user @ host
|
||||
if attached read-write, `<spies>' if only users in spy mode, or `<none>').
|
||||
@ -302,7 +302,7 @@ were typed).
|
||||
.PP
|
||||
The
|
||||
.B \-i
|
||||
option outputs information regarding each console in 12 colon-separated fields.
|
||||
option outputs information regarding each console in 13 colon-separated fields.
|
||||
.TP
|
||||
.I name
|
||||
The name of the console.
|
||||
@ -337,7 +337,7 @@ Each user bundle is seperated by commas.
|
||||
.TP
|
||||
.I state
|
||||
The state of the console.
|
||||
Values with either be ``up'' or ``down''.
|
||||
Values with either be ``up'', ``down'', or ``init''.
|
||||
.TP
|
||||
.I perm
|
||||
This value will either be ``rw'' or ``ro''.
|
||||
@ -366,6 +366,9 @@ The console aliases are presented in a comma seperated list.
|
||||
.TP
|
||||
.I options
|
||||
The active options for the console are presented in a comma seperated list.
|
||||
.TP
|
||||
.I initcmd
|
||||
The initcmd configuration option for the console.
|
||||
.SH "ESCAPE SEQUENCES"
|
||||
The connection can be controlled by a two-character escape sequence, followed
|
||||
by a command.
|
||||
@ -535,6 +538,9 @@ Never run
|
||||
from within a console connection (unless you set each
|
||||
escape sequence differently).
|
||||
.PP
|
||||
The \-i output can produce more than the stated number of fields of
|
||||
information if the user-provided information has embedded colons.
|
||||
.PP
|
||||
I'm sure there are more, I just don't know where they are.
|
||||
Please let me know if you find any.
|
||||
.SH AUTHORS
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: getpassword.c,v 1.6 2003-09-12 10:36:19-07 bryan Exp $
|
||||
* $Id: getpassword.c,v 1.7 2003-09-28 12:29:17-07 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -45,7 +45,7 @@ C2Raw(fd)
|
||||
|
||||
if (0 != tcgetattr(fd, &o_tios)) {
|
||||
Error("tcgetattr(%d): %s", fd, strerror(errno));
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
n_tios = o_tios;
|
||||
n_tios.c_iflag &= ~(IUCLC | IXON);
|
||||
@ -55,7 +55,7 @@ C2Raw(fd)
|
||||
n_tios.c_cc[VTIME] = 0;
|
||||
if (0 != tcsetattr(fd, TCSANOW, &n_tios)) {
|
||||
Error("tcsetattr(%d, TCSANOW): %s", fd, strerror(errno));
|
||||
exit(EX_UNAVAILABLE);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
screwy = 1;
|
||||
}
|
||||
|
@ -1,5 +1,11 @@
|
||||
Various contributions by folks....
|
||||
|
||||
chat
|
||||
Author: Greg Woods <woods@weird.com>
|
||||
Synopsis: A send/expect program...source code from the NetBSD
|
||||
distribution and modified by Greg Woods to work
|
||||
a bit better with conserver
|
||||
|
||||
solaris-package
|
||||
Author: Michael Sullivan <mike@trdlnk.com>
|
||||
Synopsis: Creates a solaris package
|
||||
@ -18,5 +24,5 @@ will be helpful.
|
||||
Bryan Stansell
|
||||
|
||||
#
|
||||
# $Id: README,v 1.3 2002-10-13 19:57:44-07 bryan Exp $
|
||||
# $Id: README,v 1.4 2003-09-29 07:29:37-07 bryan Exp $
|
||||
#
|
||||
|
52
contrib/chat/Makefile.in
Normal file
52
contrib/chat/Makefile.in
Normal file
@ -0,0 +1,52 @@
|
||||
### Path settings
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
bindir = @bindir@
|
||||
sysconfdir = @sysconfdir@
|
||||
mandir = @mandir@
|
||||
|
||||
### Installation programs and flags
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@ -s
|
||||
LN_S = @LN_S@
|
||||
MKDIR = @MKDIR@
|
||||
|
||||
### Compiler and link options
|
||||
CC = @CC@
|
||||
CFLAGS = @CFLAGS@
|
||||
DEFS = @DEFS@
|
||||
CPPFLAGS = -I$(top_srcdir) -I$(srcdir) $(DEFS) @CPPFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
@SET_MAKE@
|
||||
|
||||
|
||||
### Makefile rules - no user-servicable parts below
|
||||
|
||||
CHAT_OBJS = chat.o
|
||||
CHAT_HDRS = ../../config.h
|
||||
ALL = chat
|
||||
|
||||
all: $(ALL)
|
||||
|
||||
chat: $(CHAT_OBJS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o chat $(CHAT_OBJS) $(LIBS)
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f *~ *.o $(ALL) core
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile
|
||||
|
||||
install: chat
|
||||
$(MKDIR) $(DESTDIR)$(bindir)
|
||||
$(INSTALL_PROGRAM) chat $(DESTDIR)$(bindir)
|
||||
$(MKDIR) $(DESTDIR)$(mandir)/man1
|
||||
$(INSTALL) chat.man $(DESTDIR)$(mandir)/man1/chat.1
|
||||
|
||||
.PHONY: clean distclean install
|
8
contrib/chat/README
Normal file
8
contrib/chat/README
Normal file
@ -0,0 +1,8 @@
|
||||
Information from Greg Woods <woods@weird.com>:
|
||||
|
||||
This version of "chat" is derived from the NetBSD variant found in
|
||||
/usr/src/usr.sbin/pppd/chat.
|
||||
|
||||
It has had a new '-I' command-line flag added so that it can ignore
|
||||
the fact it's not running on a TTY device (i.e. to allow it to work
|
||||
over a socket).
|
1762
contrib/chat/chat.c
Normal file
1762
contrib/chat/chat.c
Normal file
File diff suppressed because it is too large
Load Diff
511
contrib/chat/chat.man
Normal file
511
contrib/chat/chat.man
Normal file
@ -0,0 +1,511 @@
|
||||
.\" -*- nroff -*-
|
||||
.\" manual page [] for chat 1.8
|
||||
.\" Id: chat.8,v 1.9 1999/09/06 05:10:23 paulus Exp
|
||||
.\" SH section heading
|
||||
.\" SS subsection heading
|
||||
.\" LP paragraph
|
||||
.\" IP indented paragraph
|
||||
.\" TP hanging label
|
||||
.TH CHAT 8 "22 May 1999" "Chat Version 1.22"
|
||||
.SH "NAME"
|
||||
chat \- Automated conversational script with a modem
|
||||
.SH "SYNOPSIS"
|
||||
.B chat
|
||||
[
|
||||
.I options
|
||||
]
|
||||
.I script
|
||||
.SH "DESCRIPTION"
|
||||
.LP
|
||||
The \fIchat\fR program defines a conversational exchange between the
|
||||
computer and the modem. Its primary purpose is to establish the
|
||||
connection between the Point-to-Point Protocol Daemon (\fIpppd\fR) and
|
||||
the remote's \fIpppd\fR process.
|
||||
.SH "OPTIONS"
|
||||
.TP
|
||||
.B -f \fI<chat file>
|
||||
Read the chat script from the chat \fIfile\fR. The use of this option
|
||||
is mutually exclusive with the chat script parameters. The user must
|
||||
have read access to the file. Multiple lines are permitted in the
|
||||
file. Space or horizontal tab characters should be used to separate
|
||||
the strings.
|
||||
.TP
|
||||
.B -t \fI<timeout>
|
||||
Set the timeout for the expected string to be received. If the string
|
||||
is not received within the time limit then the reply string is not
|
||||
sent. An alternate reply may be sent or the script will fail if there
|
||||
is no alternate reply string. A failed script will cause the
|
||||
\fIchat\fR program to terminate with a non-zero error code.
|
||||
.TP
|
||||
.B -r \fI<report file>
|
||||
Set the file for output of the report strings. If you use the keyword
|
||||
\fIREPORT\fR, the resulting strings are written to this file. If this
|
||||
option is not used and you still use \fIREPORT\fR keywords, the
|
||||
\fIstderr\fR file is used for the report strings.
|
||||
.TP
|
||||
.B -e
|
||||
Start with the echo option turned on. Echoing may also be turned on
|
||||
or off at specific points in the chat script by using the \fIECHO\fR
|
||||
keyword. When echoing is enabled, all output from the modem is echoed
|
||||
to \fIstderr\fR.
|
||||
.TP
|
||||
.B -E
|
||||
Enables environment variable substituion within chat scripts using the
|
||||
standard \fI$xxx\fR syntax.
|
||||
.TP
|
||||
.B -v
|
||||
Request that the \fIchat\fR script be executed in a verbose mode. The
|
||||
\fIchat\fR program will then log the execution state of the chat
|
||||
script as well as all text received from the modem and the output
|
||||
strings sent to the modem. The default is to log through the SYSLOG;
|
||||
the logging method may be altered with the -S and -s flags. SYSLOGs
|
||||
are logged to facility LOG_LOCAL2.
|
||||
.TP
|
||||
.B -V
|
||||
Request that the \fIchat\fR script be executed in a stderr verbose
|
||||
mode. The \fIchat\fR program will then log all text received from the
|
||||
modem and the output strings sent to the modem to the stderr device. This
|
||||
device is usually the local console at the station running the chat or
|
||||
pppd program.
|
||||
.TP
|
||||
.B -s
|
||||
Use stderr. All log messages from '-v' and all error messages will be
|
||||
sent to stderr.
|
||||
.TP
|
||||
.B -S
|
||||
Do not use the SYSLOG. By default, error messages are sent to the
|
||||
SYSLOG. The use of -S will prevent both log messages from '-v' and
|
||||
error messages from being sent to the SYSLOG (to facility LOG_LOCAL2).
|
||||
.TP
|
||||
.B -T \fI<phone number>
|
||||
Pass in an arbitary string, usually a phone number, that will be
|
||||
substituted for the \eT substitution metacharacter in a send string.
|
||||
.TP
|
||||
.B -U \fI<phone number 2>
|
||||
Pass in a second string, usually a phone number, that will be
|
||||
substituted for the \eU substitution metacharacter in a send string.
|
||||
This is useful when dialing an ISDN terminal adapter that requires two
|
||||
numbers.
|
||||
.TP
|
||||
.B script
|
||||
If the script is not specified in a file with the \fI-f\fR option then
|
||||
the script is included as parameters to the \fIchat\fR program.
|
||||
.SH "CHAT SCRIPT"
|
||||
.LP
|
||||
The \fIchat\fR script defines the communications.
|
||||
.LP
|
||||
A script consists of one or more "expect-send" pairs of strings,
|
||||
separated by spaces, with an optional "subexpect-subsend" string pair,
|
||||
separated by a dash as in the following example:
|
||||
.IP
|
||||
ogin:-BREAK-ogin: ppp ssword: hello2u2
|
||||
.LP
|
||||
This line indicates that the \fIchat\fR program should expect the string
|
||||
"ogin:". If it fails to receive a login prompt within the time interval
|
||||
allotted, it is to send a break sequence to the remote and then expect the
|
||||
string "ogin:". If the first "ogin:" is received then the break sequence is
|
||||
not generated.
|
||||
.LP
|
||||
Once it received the login prompt the \fIchat\fR program will send the
|
||||
string ppp and then expect the prompt "ssword:". When it receives the
|
||||
prompt for the password, it will send the password hello2u2.
|
||||
.LP
|
||||
A carriage return is normally sent following the reply string. It is not
|
||||
expected in the "expect" string unless it is specifically requested by using
|
||||
the \er character sequence.
|
||||
.LP
|
||||
The expect sequence should contain only what is needed to identify the
|
||||
string. Since it is normally stored on a disk file, it should not contain
|
||||
variable information. It is generally not acceptable to look for time
|
||||
strings, network identification strings, or other variable pieces of data as
|
||||
an expect string.
|
||||
.LP
|
||||
To help correct for characters which may be corrupted during the initial
|
||||
sequence, look for the string "ogin:" rather than "login:". It is possible
|
||||
that the leading "l" character may be received in error and you may never
|
||||
find the string even though it was sent by the system. For this reason,
|
||||
scripts look for "ogin:" rather than "login:" and "ssword:" rather than
|
||||
"password:".
|
||||
.LP
|
||||
A very simple script might look like this:
|
||||
.IP
|
||||
ogin: ppp ssword: hello2u2
|
||||
.LP
|
||||
In other words, expect ....ogin:, send ppp, expect ...ssword:, send hello2u2.
|
||||
.LP
|
||||
In actual practice, simple scripts are rare. At the vary least, you
|
||||
should include sub-expect sequences should the original string not be
|
||||
received. For example, consider the following script:
|
||||
.IP
|
||||
ogin:--ogin: ppp ssword: hello2u2
|
||||
.LP
|
||||
This would be a better script than the simple one used earlier. This would look
|
||||
for the same login: prompt, however, if one was not received, a single
|
||||
return sequence is sent and then it will look for login: again. Should line
|
||||
noise obscure the first login prompt then sending the empty line will
|
||||
usually generate a login prompt again.
|
||||
.SH "COMMENTS"
|
||||
Comments can be embedded in the chat script. A comment is a line which
|
||||
starts with the \fB#\fR (hash) character in column 1. Such comment
|
||||
lines are just ignored by the chat program. If a '#' character is to
|
||||
be expected as the first character of the expect sequence, you should
|
||||
quote the expect string, or give its octal value, `\e043'.
|
||||
In a script file if you want to wait for a prompt that starts with a '#'
|
||||
character, you would have to write something like this:
|
||||
.IP
|
||||
# Now wait for the prompt and send logout string
|
||||
.br
|
||||
\'# ' logout
|
||||
.SH "SENDING DATA FROM A FILE"
|
||||
If the string to send starts with an at sign (@), the rest of the
|
||||
string is taken to be the name of a file to read to get the string to
|
||||
send. If the last character of the data read is a newline, it is
|
||||
removed. The file can be a named pipe (or fifo) instead of a regular
|
||||
file. This provides a way for \fBchat\fR to communicate with another
|
||||
program, for example, a program to prompt the user and receive a
|
||||
password typed in.
|
||||
.SH "ABORT STRINGS"
|
||||
Many modems will report the status of the call as a string. These
|
||||
strings may be \fBCONNECTED\fR or \fBNO CARRIER\fR or \fBBUSY\fR. It
|
||||
is often desirable to terminate the script should the modem fail to
|
||||
connect to the remote. The difficulty is that a script would not know
|
||||
exactly which modem string it may receive. On one attempt, it may
|
||||
receive \fBBUSY\fR while the next time it may receive \fBNO CARRIER\fR.
|
||||
.LP
|
||||
These "abort" strings may be specified in the script using the \fIABORT\fR
|
||||
sequence. It is written in the script as in the following example:
|
||||
.IP
|
||||
ABORT BUSY ABORT 'NO CARRIER' '' ATZ OK ATDT5551212 CONNECT
|
||||
.LP
|
||||
This sequence will expect nothing; and then send the string ATZ. The
|
||||
expected response to this is the string \fIOK\fR. When it receives \fIOK\fR,
|
||||
the string ATDT5551212 to dial the telephone. The expected string is
|
||||
\fICONNECT\fR. If the string \fICONNECT\fR is received the remainder of the
|
||||
script is executed. However, should the modem find a busy telephone, it will
|
||||
send the string \fIBUSY\fR. This will cause the string to match the abort
|
||||
character sequence. The script will then fail because it found a match to
|
||||
the abort string. If it received the string \fINO CARRIER\fR, it will abort
|
||||
for the same reason. Either string may be received. Either string will
|
||||
terminate the \fIchat\fR script.
|
||||
.SH "CLR_ABORT STRINGS"
|
||||
This sequence allows for clearing previously set \fBABORT\fR strings.
|
||||
\fBABORT\fR strings are kept in an array of a pre-determined size (at
|
||||
compilation time); \fBCLR_ABORT\fR will reclaim the space for cleared
|
||||
entries so that new strings can use that space.
|
||||
.SH "SAY STRINGS"
|
||||
The \fBSAY\fR directive allows the script to send strings to the user
|
||||
at the terminal via standard error. If \fBchat\fR is being run by
|
||||
pppd, and pppd is running as a daemon (detached from its controlling
|
||||
terminal), standard error will normally be redirected to the file
|
||||
/etc/ppp/connect-errors.
|
||||
.LP
|
||||
\fBSAY\fR strings must be enclosed in single or double quotes. If
|
||||
carriage return and line feed are needed in the string to be output,
|
||||
you must explicitly add them to your string.
|
||||
.LP
|
||||
The SAY strings could be used to give progress messages in sections of
|
||||
the script where you want to have 'ECHO OFF' but still let the user
|
||||
know what is happening. An example is:
|
||||
.IP
|
||||
ABORT BUSY
|
||||
.br
|
||||
ECHO OFF
|
||||
.br
|
||||
SAY "Dialling your ISP...\en"
|
||||
.br
|
||||
\'' ATDT5551212
|
||||
.br
|
||||
TIMEOUT 120
|
||||
.br
|
||||
SAY "Waiting up to 2 minutes for connection ... "
|
||||
.br
|
||||
CONNECT ''
|
||||
.br
|
||||
SAY "Connected, now logging in ...\n"
|
||||
.br
|
||||
ogin: account
|
||||
.br
|
||||
ssword: pass
|
||||
.br
|
||||
$ \c
|
||||
SAY "Logged in OK ...\n"
|
||||
\fIetc ...\fR
|
||||
.LP
|
||||
This sequence will only present the SAY strings to the user and all
|
||||
the details of the script will remain hidden. For example, if the
|
||||
above script works, the user will see:
|
||||
.IP
|
||||
Dialling your ISP...
|
||||
.br
|
||||
Waiting up to 2 minutes for connection ... Connected, now logging in ...
|
||||
.br
|
||||
Logged in OK ...
|
||||
.LP
|
||||
.SH "REPORT STRINGS"
|
||||
A \fBreport\fR string is similar to the ABORT string. The difference
|
||||
is that the strings, and all characters to the next control character
|
||||
such as a carriage return, are written to the report file.
|
||||
.LP
|
||||
The report strings may be used to isolate the transmission rate of the
|
||||
modem's connect string and return the value to the chat user. The
|
||||
analysis of the report string logic occurs in conjunction with the
|
||||
other string processing such as looking for the expect string. The use
|
||||
of the same string for a report and abort sequence is probably not
|
||||
very useful, however, it is possible.
|
||||
.LP
|
||||
The report strings to no change the completion code of the program.
|
||||
.LP
|
||||
These "report" strings may be specified in the script using the \fIREPORT\fR
|
||||
sequence. It is written in the script as in the following example:
|
||||
.IP
|
||||
REPORT CONNECT ABORT BUSY '' ATDT5551212 CONNECT '' ogin: account
|
||||
.LP
|
||||
This sequence will expect nothing; and then send the string
|
||||
ATDT5551212 to dial the telephone. The expected string is
|
||||
\fICONNECT\fR. If the string \fICONNECT\fR is received the remainder
|
||||
of the script is executed. In addition the program will write to the
|
||||
expect-file the string "CONNECT" plus any characters which follow it
|
||||
such as the connection rate.
|
||||
.SH "CLR_REPORT STRINGS"
|
||||
This sequence allows for clearing previously set \fBREPORT\fR strings.
|
||||
\fBREPORT\fR strings are kept in an array of a pre-determined size (at
|
||||
compilation time); \fBCLR_REPORT\fR will reclaim the space for cleared
|
||||
entries so that new strings can use that space.
|
||||
.SH "ECHO"
|
||||
The echo options controls whether the output from the modem is echoed
|
||||
to \fIstderr\fR. This option may be set with the \fI-e\fR option, but
|
||||
it can also be controlled by the \fIECHO\fR keyword. The "expect-send"
|
||||
pair \fIECHO\fR \fION\fR enables echoing, and \fIECHO\fR \fIOFF\fR
|
||||
disables it. With this keyword you can select which parts of the
|
||||
conversation should be visible. For instance, with the following
|
||||
script:
|
||||
.IP
|
||||
ABORT 'BUSY'
|
||||
.br
|
||||
ABORT 'NO CARRIER'
|
||||
.br
|
||||
'' ATZ
|
||||
.br
|
||||
OK\er\en ATD1234567
|
||||
.br
|
||||
\er\en \ec
|
||||
.br
|
||||
ECHO ON
|
||||
.br
|
||||
CONNECT \ec
|
||||
.br
|
||||
ogin: account
|
||||
.LP
|
||||
all output resulting from modem configuration and dialing is not visible,
|
||||
but starting with the \fICONNECT\fR (or \fIBUSY\fR) message, everything
|
||||
will be echoed.
|
||||
.SH "HANGUP"
|
||||
The HANGUP options control whether a modem hangup should be considered
|
||||
as an error or not. This option is useful in scripts for dialling
|
||||
systems which will hang up and call your system back. The HANGUP
|
||||
options can be \fBON\fR or \fBOFF\fR.
|
||||
.br
|
||||
When HANGUP is set OFF and the modem hangs up (e.g., after the first
|
||||
stage of logging in to a callback system), \fBchat\fR will continue
|
||||
running the script (e.g., waiting for the incoming call and second
|
||||
stage login prompt). As soon as the incoming call is connected, you
|
||||
should use the \fBHANGUP ON\fR directive to reinstall normal hang up
|
||||
signal behavior. Here is an (simple) example script:
|
||||
.IP
|
||||
ABORT 'BUSY'
|
||||
.br
|
||||
'' ATZ
|
||||
.br
|
||||
OK\er\en ATD1234567
|
||||
.br
|
||||
\er\en \ec
|
||||
.br
|
||||
CONNECT \ec
|
||||
.br
|
||||
\'Callback login:' call_back_ID
|
||||
.br
|
||||
HANGUP OFF
|
||||
.br
|
||||
ABORT "Bad Login"
|
||||
.br
|
||||
\'Callback Password:' Call_back_password
|
||||
.br
|
||||
TIMEOUT 120
|
||||
.br
|
||||
CONNECT \ec
|
||||
.br
|
||||
HANGUP ON
|
||||
.br
|
||||
ABORT "NO CARRIER"
|
||||
.br
|
||||
ogin:--BREAK--ogin: real_account
|
||||
.br
|
||||
\fIetc ...\fR
|
||||
.LP
|
||||
.SH "TIMEOUT"
|
||||
The initial timeout value is 45 seconds. This may be changed using the \fB-t\fR
|
||||
parameter.
|
||||
.LP
|
||||
To change the timeout value for the next expect string, the following
|
||||
example may be used:
|
||||
.IP
|
||||
ATZ OK ATDT5551212 CONNECT TIMEOUT 10 ogin:--ogin: TIMEOUT 5 assword: hello2u2
|
||||
.LP
|
||||
This will change the timeout to 10 seconds when it expects the login:
|
||||
prompt. The timeout is then changed to 5 seconds when it looks for the
|
||||
password prompt.
|
||||
.LP
|
||||
The timeout, once changed, remains in effect until it is changed again.
|
||||
.SH "SENDING EOT"
|
||||
The special reply string of \fIEOT\fR indicates that the chat program
|
||||
should send an EOT character to the remote. This is normally the
|
||||
End-of-file character sequence. A return character is not sent
|
||||
following the EOT.
|
||||
.PR
|
||||
The EOT sequence may be embedded into the send string using the
|
||||
sequence \fI^D\fR.
|
||||
.SH "GENERATING BREAK"
|
||||
The special reply string of \fIBREAK\fR will cause a break condition
|
||||
to be sent. The break is a special signal on the transmitter. The
|
||||
normal processing on the receiver is to change the transmission rate.
|
||||
It may be used to cycle through the available transmission rates on
|
||||
the remote until you are able to receive a valid login prompt.
|
||||
.PR
|
||||
The break sequence may be embedded into the send string using the
|
||||
\fI\eK\fR sequence.
|
||||
.SH "ESCAPE SEQUENCES"
|
||||
The expect and reply strings may contain escape sequences. All of the
|
||||
sequences are legal in the reply string. Many are legal in the expect.
|
||||
Those which are not valid in the expect sequence are so indicated.
|
||||
.TP
|
||||
.B ''
|
||||
Expects or sends a null string. If you send a null string then it will still
|
||||
send the return character. This sequence may either be a pair of apostrophe
|
||||
or quote characters.
|
||||
.TP
|
||||
.B \eb
|
||||
represents a backspace character.
|
||||
.TP
|
||||
.B \ec
|
||||
Suppresses the newline at the end of the reply string. This is the only
|
||||
method to send a string without a trailing return character. It must
|
||||
be at the end of the send string. For example,
|
||||
the sequence hello\ec will simply send the characters h, e, l, l, o.
|
||||
.I (not valid in expect.)
|
||||
.TP
|
||||
.B \ed
|
||||
Delay for one second. The program uses sleep(1) which will delay to a
|
||||
maximum of one second.
|
||||
.I (not valid in expect.)
|
||||
.TP
|
||||
.B \eK
|
||||
Insert a BREAK
|
||||
.I (not valid in expect.)
|
||||
.TP
|
||||
.B \en
|
||||
Send a newline or linefeed character.
|
||||
.TP
|
||||
.B \eN
|
||||
Send a null character. The same sequence may be represented by \e0.
|
||||
.I (not valid in expect.)
|
||||
.TP
|
||||
.B \ep
|
||||
Pause for a fraction of a second. The delay is 1/10th of a second.
|
||||
.I (not valid in expect.)
|
||||
.TP
|
||||
.B \eq
|
||||
Suppress writing the string to the SYSLOG. The string ?????? is
|
||||
written to the log in its place.
|
||||
.I (not valid in expect.)
|
||||
.TP
|
||||
.B \er
|
||||
Send or expect a carriage return.
|
||||
.TP
|
||||
.B \es
|
||||
Represents a space character in the string. This may be used when it
|
||||
is not desirable to quote the strings which contains spaces. The
|
||||
sequence 'HI\ TIM' and HI\esTIM are the same.
|
||||
.TP
|
||||
.B \et
|
||||
Send or expect a tab character.
|
||||
.TP
|
||||
.B \eT
|
||||
Send the phone number string as specified with the \fI-T\fR option
|
||||
.I (not valid in expect.)
|
||||
.TP
|
||||
.B \eU
|
||||
Send the phone number 2 string as specified with the \fI-U\fR option
|
||||
.I (not valid in expect.)
|
||||
.TP
|
||||
.B \e\e
|
||||
Send or expect a backslash character.
|
||||
.TP
|
||||
.B \eddd
|
||||
Collapse the octal digits (ddd) into a single ASCII character and send that
|
||||
character.
|
||||
.I (some characters are not valid in expect.)
|
||||
.TP
|
||||
.B \^^C
|
||||
Substitute the sequence with the control character represented by C.
|
||||
For example, the character DC1 (17) is shown as \^^Q.
|
||||
.I (some characters are not valid in expect.)
|
||||
.SH "ENVIRONMENT VARIABLES"
|
||||
Environment variables are available within chat scripts, if the \fI-E\fR
|
||||
option was specified in the command line. The metacharacter \fI$\fR is used
|
||||
to introduce the name of the environment variable to substitute. If the
|
||||
substition fails, because the requested environment variable is not set,
|
||||
\fInothing\fR is replaced for the variable.
|
||||
.SH "TERMINATION CODES"
|
||||
The \fIchat\fR program will terminate with the following completion
|
||||
codes.
|
||||
.TP
|
||||
.B 0
|
||||
The normal termination of the program. This indicates that the script
|
||||
was executed without error to the normal conclusion.
|
||||
.TP
|
||||
.B 1
|
||||
One or more of the parameters are invalid or an expect string was too
|
||||
large for the internal buffers. This indicates that the program as not
|
||||
properly executed.
|
||||
.TP
|
||||
.B 2
|
||||
An error occurred during the execution of the program. This may be due
|
||||
to a read or write operation failing for some reason or chat receiving
|
||||
a signal such as SIGINT.
|
||||
.TP
|
||||
.B 3
|
||||
A timeout event occurred when there was an \fIexpect\fR string without
|
||||
having a "-subsend" string. This may mean that you did not program the
|
||||
script correctly for the condition or that some unexpected event has
|
||||
occurred and the expected string could not be found.
|
||||
.TP
|
||||
.B 4
|
||||
The first string marked as an \fIABORT\fR condition occurred.
|
||||
.TP
|
||||
.B 5
|
||||
The second string marked as an \fIABORT\fR condition occurred.
|
||||
.TP
|
||||
.B 6
|
||||
The third string marked as an \fIABORT\fR condition occurred.
|
||||
.TP
|
||||
.B 7
|
||||
The fourth string marked as an \fIABORT\fR condition occurred.
|
||||
.TP
|
||||
.B ...
|
||||
The other termination codes are also strings marked as an \fIABORT\fR
|
||||
condition.
|
||||
.LP
|
||||
Using the termination code, it is possible to determine which event
|
||||
terminated the script. It is possible to decide if the string "BUSY"
|
||||
was received from the modem as opposed to "NO DIAL TONE". While the
|
||||
first event may be retried, the second will probably have little
|
||||
chance of succeeding during a retry.
|
||||
.SH "SEE ALSO"
|
||||
Additional information about \fIchat\fR scripts may be found with UUCP
|
||||
documentation. The \fIchat\fR script was taken from the ideas proposed
|
||||
by the scripts used by the \fIuucico\fR program.
|
||||
.LP
|
||||
uucp(1), uucico(8)
|
||||
.SH "COPYRIGHT"
|
||||
The \fIchat\fR program is in public domain. This is not the GNU public
|
||||
license. If it breaks then you get to keep both pieces.
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
|
||||
%define pkg conserver
|
||||
%define ver conserver-8.0.0
|
||||
%define ver conserver-8.0.1
|
||||
|
||||
# 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="conserver-8.0.0"
|
||||
VERSION="conserver-8.0.1"
|
||||
DESC="Console server and client"
|
||||
CLASSES=none
|
||||
ARCH=sparc
|
||||
|
Loading…
Reference in New Issue
Block a user