[comp.unix.xenix] cu/uucp suspend/restart getty - how?

rac@sherpa.UUCP (Roger Cornelius) (06/10/90)

Can someone enlighten me as to how uucp and cu signal getty to suspend
and restart with SCO's HDB uucp?  I recall discussion here about
manually using SIGUSR1 and SIGUSR2 to accomplish this, but I'd like to
understand how cu/uucp do it (ie., from within a C program).

This is under SCO UNIX but uucp's behavior in this respect seems to be
the same as XENIX's.

--
Roger A. Cornelius          rac@sherpa.UUCP         uunet!sherpa!rac

davidsen@sixhub.UUCP (Wm E. Davidsen Jr) (06/10/90)

In article <272@sherpa.UUCP> rac@sherpa.UUCP (Roger Cornelius) writes:
| 
| Can someone enlighten me as to how uucp and cu signal getty to suspend
| and restart with SCO's HDB uucp?  I recall discussion here about
| manually using SIGUSR1 and SIGUSR2 to accomplish this, but I'd like to
| understand how cu/uucp do it (ie., from within a C program).

     Name
	  kill - Sends a signal	to a process or	a group	of processes.

     Syntax
	  #include <signal.h>

	  int kill (pid, sig)
	  int pid, sig;

  The hard part is getting the PID of the getty, and the info you want
can be found in utmp.h (to human read) and either /usr/adm/wtmp or
/etc/wtmp (for program reading at runtime). See man section utmp.

  Logic:

	-  Scan utmp for a getty. 
	-  Get the line # from the entry. 
	-  Send SIGUSR1 to the getty using kill(). 
	-  Use the line. 
	-  Send SIGUSR2 to the getty.
-- 
bill davidsen - davidsen@sixhub.uucp (uunet!crdgw1!sixhub!davidsen)
    sysop *IX BBS and Public Access UNIX
    moderator of comp.binaries.ibm.pc and 80386 mailing list
"Stupidity, like virtue, is its own reward" -me

wht@n4hgf.uucp (Warren Tucker) (06/11/90)

In article <272@sherpa.UUCP> rac@sherpa.UUCP (Roger Cornelius) writes:
>
>Can someone enlighten me as to how uucp and cu signal getty to suspend
>and restart with SCO's HDB uucp?  I recall discussion here about
>manually using SIGUSR1 and SIGUSR2 to accomplish this, but I'd like to
>understand how cu/uucp do it (ie., from within a C program).
>
>This is under SCO UNIX but uucp's behavior in this respect seems to be
>the same as XENIX's.
>
>--
>Roger A. Cornelius          rac@sherpa.UUCP         uunet!sherpa!rac

Just create a lock file in /usr/spool/uucp using the LOWER case filename.
To lock /dev/tty1A or /dev/tty1a, create /usr/spool/uucp/LCK..tty1a.
THEN, open the file with O_NDELAY.  Both /etc/getty and /usr/lib/uucp/
uugetty will sense the presence of the lock file and loop, waiting
until it goes away.  Then getty dies and is respawned by init.

Here is some code that may not be complete, but will give you the 
right ideas:

char LCKname[64] = "";

/*+-------------------------------------------------------------------------
    create_lock_file(name)
--------------------------------------------------------------------------*/
int
create_lock_file(name)
char *name;
{
register fd;
int pid = getpid();
#if defined(HONEYDANBER)
char pid10str[12];

    sprintf(pid10str,"%10d\n",getpid());

    errno = 0;
    sprintf(LTMP_fname,"/usr/spool/uucp/LTMP.%05d",pid);
    if((fd = creat(LTMP_fname,0444)) < 0)
        return(-1);
    write(fd,pid10str,11);
    chmod(LTMP_fname,0444);
    close(fd);
    fd = link(LTMP_fname,name);     /* use 'fd' for link return code */
    unlink(LTMP_fname);
    chmod(name,0444);
    return(fd);
}   /* end of create_lock_file */

/*+-------------------------------------------------------------------------
    is_active_lock(name) - check to see if lock still active

if so, return pid of active owner
if error, return -1
if not unlink any old lock name and return 0
--------------------------------------------------------------------------*/
is_active_lock(name)
register char *name;
{
register itmp;
int lockpid;
int fd;
char pidstr[12];

    errno = 0;
    if((fd = open(name,O_RDONLY,0)) < 0)
    {
        if(errno != ENOENT)
            return(-1);
    }

    itmp = read(fd,(char *)pidstr,11);
    pidstr[11] = 0;
    close(fd);
    if(itmp != 11)
        goto UNLINK_OLD_LOCK;
    lockpid = atoi(pidstr);

    if((!(kill(lockpid,0))) || (errno != ESRCH))
    {
        errno = EACCES;
        return(lockpid);
    }
    if(unlink(name))
        return(-1);
    return(0);
}   /* end of is_active_lock */

/*+-------------------------------------------------------------------------
    lock_tty(Ttyname) - create lock files for tty name in 'Ttyname'

return 0 if lock successful, >0 == pid of owner, else -1 if error
--------------------------------------------------------------------------*/
int
lock_tty(Ttyname)
char *Ttyname; /* of the form "ttyxx" */
{
register itmp;

    sprintf(LCKname,"/usr/spool/LCK..%s",Ttyname);
    itmp = strlen(LCKname) - 1;
    if(isupper(LCKname[itmp]))      /* create lock using lower case dev name */
        LCKname[itmp] = tolower(LCKname[itmp]);

    if(create_lock_file(LCKname))
    {
        if(itmp = is_active_lock(LCKname))
        {
            LCKname[0] = 0;
            errno = EACCES;
            return(itmp);
        }
        if(create_lock_file(LCKname))
        {
            LCKname[0] = 0;
            errno = EACCES; /* for hangup() */
            return(-1);
        }
    }

    return(0);
}   /* end of lock_tty */

/*+-----------------------------------------------------------------------
    unlock_tty()
------------------------------------------------------------------------*/
void
unlock_tty()
{
    if(LCKname[0])
    {
        unlink(LCKname);
        LCKname[0] = 0;
    }
}   /* end of unlock_tty */

/*+-------------------------------------------------------------------------
	use_tty(Ttyname) - Ttyname of the form "tty1a"
--------------------------------------------------------------------------*/
use_tty(Ttyname)
{
char tty[64];
int fd;
int stat;

	if(!(stat = lock_tty(Ttyname)))
	{
		strcpy(tty,"/dev/");
		strcat(tty,Ttyname);
		if(fd = open(tty,O_RDWR|O_NDELAY,0))
		{
			do your thing (make sure you set HUPCL with ioctl)
		}
		close(fd);
		unlock_tty();
	}
	else if(stat > 0)
		printf("tty %s in use by pid %d\n",Ttyname,stat);
	else if(stat > 0)
		printf("error locking tty %s\n",Ttyname);
}	/* end of use_tty */

 
---------------------------------------------------------------------
Warren Tucker, TuckerWare    gatech!n4hgf!wht or wht%n4hgf@gatech.edu
Any perceptible delay will eventually get on your nerves. --Bob Hyers

rac@sherpa.UUCP (Roger Cornelius) (06/11/90)

From article <1137@sixhub.UUCP>, by davidsen@sixhub.UUCP (Wm E. Davidsen Jr):
| In article <272@sherpa.UUCP> rac@sherpa.UUCP (Roger Cornelius) writes:
| | 
| | Can someone enlighten me as to how uucp and cu signal getty to suspend
| | and restart with SCO's HDB uucp?  I recall discussion here about
| | manually using SIGUSR1 and SIGUSR2 to accomplish this, but I'd like to
| | understand how cu/uucp do it (ie., from within a C program).
| 
|   Logic:
| 	-  Scan utmp for a getty. 
| 	-  Get the line # from the entry. 
| 	-  Send SIGUSR1 to the getty using kill(). 
| 	-  Use the line. 
| 	-  Send SIGUSR2 to the getty.

But the getty process is owned by root and cu/uucp are suid uucp.  How
can they kill the process (with kill())?  Either I'm missing something
or the above isn't correct (at least for cu/uucp - I agree it should
work for a process running as root).

So how can a process owned by uucp suspend/restart the getty?
-- 
Roger A. Cornelius          rac@sherpa.UUCP         uunet!sherpa!rac