[net.unix-wizards] un-dedicating a line to a dialer

steve@lpi3230.UUCP (Steve Burbeck) (12/19/83)

We (and many others I would guess) have a similar problem.  We
solved it without kernel hacks.  The trick requires the ability to
detach the tty line and reattach it later, which some systems do
not support (ours is Perkin-Elmer V7 which has detach and attach
commands).  All you need to do is have two L.sys files: I call them
L.sys.Any and L.sys.Never.  During normal times when the tty is
attached and used for dial-in, L.sys is linked to L.sys.Never in
which all sites that require use of the tty for dial-out have
Never in the call-time field so mail for them is spooled, but
uucico will not attempt to dial out.  When dial out is desired
(e.g., by crontab every night or whenever the super-user desires)
a shell script  called uucp_out tests to be sure that the line is not
in use, and if not, detaches the tty line, relinks L.sys to L.sys.Any,
and starts uucico.  L.sys.Any has Any in the call-time field for those
sites that require dial-out.  When uucico is done, L.sys is relinked
to L.sys.Never and the tty line is attached.

This may seem like a kludge, but it is a lifesaver for those of us
that do not have access to kernel source.  The system has worked
smoothly for months now.

bob@onyx.UUCP (Bob Toxen) (12/22/83)

We solved the getty/uucico problem by hacking  getty  to  respect
uucico's  /usr/spool/uucp/LCK..ttyxx  and  when  it  successfully
grabbed  the   lock   to   create   one   of   its   own   called
/usr/spool/uucp/LCK.g2.ttyxx  which  means:  "I have the line but
I'm just waiting for someone to  login  [our  tty  driver/  modem
combo  have  the problem that the modem will only assert RTS when
someone calls in but not when you want to call out]  but  if  you
send  me  a  SIGTERM  or  SIGHUP  I'll close the file, 'chmod 666
/dev/ttyxx', and remove the locks (LCK.g2.ttyxx first) and wait a
minute  before  again trying to grab LCK..ttyxx". Be sure to also
do this before getty exits in any fashion.

When getty is about to exec login it first  creates  LCK.g3.ttyxx
and  then unlinks LCK.g2.ttyxx. The LCK.g3.ttyxx is so that after
the person logs out the next getty will, before  trying  to  grab
LCK..ttyxx,  try  to  unlink  LCK.g3.ttyxx  and if it can it will
assume that the previous getty left this and  also  a  LCK..ttyxx
which this getty will then unlink.

UUCICO will, if LCK..ttyxx exists, check  for  the  existance  of
LCK.g2.ttyxx  BEFORE  CHECKING  THE  AGE  OF LCK..ttyxx and if it
exists then send a signal to the getty (whose binary  PID  is  in
LCK.g2.ttyxx)  via  an  intermediate  program with mode 4110 with
owner root and group uucp. This requires uucico to be  both  Set-
UID AND Set-GID to uucp.

This is more complex than I like but only takes about 30 lines of
code in each of getty and uucico (sorry, I can't supply code) and
doesn't require Kernel hacking or any intelligence in the port or
modem.

Bob Toxen  ucbvax!amd70!onyx!bob

alt%aids-unix@sri-unix.UUCP (12/29/83)

From:  Howard Alt <alt@aids-unix>

Hmmm, it seems to me that a short suid root program that:
1) looks in utmp for someone logged in
2) changes the 1 to a 0 in /etc/ttys
3) sends a HUP signal to init
and another program that:
1) changes the 0 to a 1 in /etc/ttys
2) sends a HUP signal to init

you could call these enable and disable, and make them have a tty
as an argument.  You could even have it log enables and disables,
and check a list of ttys that it is ok to disable.  

uucico could then do a system("disable ttyd0"); to make it a dialout,
and a system("enable ttyd0); to make it a normal dialin again.
Does this do the same thing you were talking about, or does it
miss a case that your method catches?  The problem I can think of
is:  Somone just calls up, types thier login name and password
and the trash appears on thier screen.  uucico decided to call 
out just before thier name was entered in utmp, and after they 
dialed up.  Does your method keep this from happening?

				Howard.

dpk%brl-vgr@sri-unix.UUCP (01/03/84)

From:      Doug Kingston <dpk@brl-vgr>

LCK.g2.ttyxx, LCK.g3.ttyxx, UUCICO and GETTY

				Yuck.
					-Doug-

dave@utcsrgv.UUCP (Dave Sherman) (01/04/84)

I have the source to programs I wrote in C called "originate" and
"answer" which do exactly what howard (alt@aids-unix) suggests -
check whether the line is free, and switch the /etc/ttys entry
and signal init. I know there are more elegant ways which
have been posted in the past, but this was easy and works without
any kernel changes or lock files. It's been running since April
on lsuc with no problems.

If anybody is interested I can mail them to you or post them to net.sources.

Dave Sherman
The Law Society of Upper Canada
Toronto
416-947-3466
allegra!utcsrgv!dave@BERKELEY
-- 
 {allegra,cornell,decvax,ihnp4,linus,utzoo}!utcsrgv!dave

cak@Purdue.ARPA (01/05/84)

From:  Christopher A Kent <cak@Purdue.ARPA>

I wrote such a program a long time ago. I have sent it to several
people already -- if there are other folks who would like a copy, send
me a note.

chris
----------

chris@basservax.SUN (01/05/84)

The solution is to have the dialler program open the dial
line with O_EXCL, which will return an error if a getty or login
still has the line open.

If you have signalled init, it is about to hangup the line anyway,
so uucico just needs to wait until its exclusive open returns.

guy@rlgvax.UUCP (Guy Harris) (01/07/84)

<anybody not fixed this bug yet?>

	The solution is to have the dialler program open the dial
	line with O_EXCL, which will return an error if a getty or login
	still has the line open.

Well, the V7 "exclusive use" bit for terminals (turned on and off by an "ioctl",
although the DZ driver (which looked suspiciously like a USG driver
retrofitted) didn't honor it) would do that, but the O_EXCL bit in System III
and 4.2BSD isn't an exclusive use open.  It permits you to use the existence
of a file as a lock - what it does is tells the kernel, when used with the
O_CREAT bit (which says "create the file if it doesn't exist), to return an
error if the file exists.

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy

brad@bradley.UUCP (01/07/84)

#R:lpi3230:-12600:bradley:3900006:000:942
bradley!brad    Jan  6 10:02:00 1984


Version: UNIX V7m 2.1
Modem: Hayes Smart

We use one of our lines for both in and out. The only way we did is via
a kernel hack, which I have not done (we are waiting for 2.9). But for
the time being we use a smilar method. In going from 1 -> 0 in the ttys
file when you try to 'open' the device the modem has not set the bit
which refers to carrier detect. In out version of UNIX a null line uses
the 'dm' potion of dh/dm insted of dh. What this means is it hangs the
open waiting for carrier. What we did, which is a bigger kludge, is go
from 1 -> 2, wait about 10-15 sec so as not to klobber init. then go
2 -> 0, and wait again. This asserts carrier on the line and allows to
dial out. Now when you hang up the phone you have to go back to 2
then go to 0 (waiting of course). This is a pain but we only talk to
three machines and are awaiting 2.9 so we can live with it.

Brad Smith, Bradley University
{ihnp4,cepu,uiucdcs}!bradley!brad

dave@utcsrgv.UUCP (Dave Sherman) (01/08/84)

I have posted the source to "originate" and "answer" to net.sources,
after a number of inquiries for it. Anyone on the Arpanet who doesn't
get net.sources, ask me.

Dave Sherman
-- 
 {allegra,cornell,decvax,ihnp4,linus,utzoo}!utcsrgv!dave

chris@basservax.SUN (Chris Maltby) (01/11/84)

Sorry about the item suggesting O_EXCL open as the
dialler solution. Long ago, we changed our various terminal
drivers to look for FEXCL in open calls, and examine and set XCLUDE
in the tty flags. It really is quite useful (see example above).

The code goes something like this:

	if ((tp->t_state&(ISOPEN|WOPEN)) == 0)
	{
		...
	}
	else if (((tp->t_state & XCLUDE) || (flag&FEXCL)) && !(flag&FFORCE))
	{
		u.u_error = ENXIO;
		return;
	}
	if (flag&FEXCL)
		tp->t_state |= XCLUDE;

FFORCE corresponds to a new open option O_FORCE (super user only)
which allows the XCLUDE to be overridden.

wls@astrovax.UUCP (William L. Sebok) (01/11/84)

> The solution is to have the dialler program open the dial
> line with O_EXCL, which will return an error if a getty or login
> still has the line open.
> 
> If you have signalled init, it is about to hangup the line anyway,
> so uucico just needs to wait until its exclusive open returns.

There is a severe problem with Exclusive Use mode on lines used for both
dialing in and dialing out.  If someone dials in and releases a long-running
background job the special file will be held open until the background job
finishes (which happens quite often on our system).  This will prevent locking
mechanisms like the above from working. 
  The 4.1 BSD uucp expected that closing the port would clear the Exclusive
use bit.  Under the above circumstances this didn't work.  The cure was to
make sure uucp cleared Exclusive use before closing the port.  Another
possible place to handle this problem is in the program that enables/disables
dialins on the port.
-- 
Bill Sebok			Princeton University, Astrophysics
{allegra,akgua,burl,cbosgd,decvax,ihnp4,kpno,princeton,vax135}!astrovax!wls

chris@basservax.SUN (Chris Maltby) (01/17/84)

 > If someone dials in and releases a long-running background job the
 > special file will be held open until the background job finishes (which
 > happens quite often on our system).  This will prevent locking mechanisms
 > like the above from working.  

A sensible system will send a HUP signal to the process group when its
leader dies, and unless the long-runner has been 'nohup'ed (and its
references to the terminal closed), it will die.

kre@mulga.SUN (Robert Elz) (01/18/84)

  > A sensible system will send a HUP signal to the process group when its
  > leader dies, and unless the long-runner has been 'nohup'ed (and its
  > references to the terminal closed), it will die.

Quite true, however, many of your average "long running" processes
ignore HUP signals, so your "sensible system" doesn't do a lot of good.

A better strategy would be to force the terminal closed when
a user logs out (not just when pgrp leader dies, as that overly
restricts the use of pgrps).

guy@rlgvax.UUCP (Guy Harris) (01/18/84)

>  > A sensible system will send a HUP signal to the process group when its
>  > leader dies, and unless the long-runner has been 'nohup'ed (and its
>  > references to the terminal closed), it will die.

> Quite true, however, many of your average "long running" processes
> ignore HUP signals, so your "sensible system" doesn't do a lot of good.

> A better strategy would be to force the terminal closed when
> a user logs out (not just when pgrp leader dies, as that overly
> restricts the use of pgrps).

I assume the "sensible system" mentioned here is USG UNIX, which does, indeed,
zap a pgrp with SIGHUP when the leader dies.  4.xBSD have the "vhangup" call
which is executed by "init" when the leader dies, which has a similar effect -
the 4.1c code (but not the 4.2 code) had comments mentioning that it should
*really* be done by the kernel (i.e., like having the USG code zap all file
descriptors referring to the tty in addition to sending the SIGHUP).

The trick is defining "the user logging out"; the definition used by USG
UNIX is "pgrp leader dying", and the definition in effect implemented by
4.xBSD is also "pgrp leader dying" (because "init" remembers the pgrp leader PID
and, when it dies, respawns "getty"); however, the 4.x implementation of
pgrps is not the same as the USG one.  4.x uses pgrps for job control, USG
(prior to S5R2, anyway) doesn't have job control so that problem doesn't
crop up.  If a system is to have the USG pgrps (along with the SIGHUP) *and*
BSD job control, there would probably need to be *two* kinds of pgrps; one
(call them "process groups") the same as vanilla USG pgrps, and one (call
them "job groups"?) the same as 4.x pgrps.  SIGINT, SIGQUIT, SIGTSTP, etc.
are sent to the job group currently associated with the terminal, while
SIGHUP is sent to the entire process group, unless it's decided that SIGHUP
shouldn't really go to background jobs even if the carrier really drops.

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy

astro@princeton.UUCP (Astrophysics) (01/18/84)

My statement
>> If someone dials in and releases a long-running background job the
>> special file will be held open until the background job finishes (which
>> happens quite often on our system).  This will prevent locking mechanisms
>> like the above from working.  

Response:
> A sensible system will send a HUP signal to the process group when its
> leader dies, and unless the long-runner has been 'nohup'ed (and its
> references to the terminal closed), it will die.

But of course!  the long-runner has been nohup'ed (or the equivalent) by a
person who dialed in for the sole reason of starting the job and then hanging
up.  The real problem here in the 4.x BSD system we run here is that even
though a vhangup call removes all of the process's access permissions to
the port it does not reinitialize the port's state.

Bill Sebok	(dialing in here till I get astrovax back up again)
{allegra,decvax,ihnp4}!astrovax!wls