ungetty interface
Sandford Zelkovitz
sandy at conexch.UUCP
Wed Jun 28 07:33:18 AEST 1989
Some time ago, I posted my method of interfacing a "home grown" getty to
SCO's ungetty. Since then, I have received many requests for a repost.
I have also extracted, from my getty, the ungetty interface which I am
including at the tail end of this message.
The interface is really pretty simple. Basically, the user code must trap
SIGUSR1 and, if you wish, SIGUSR2. I do not trap SIGUSR2 but go into a
"pause" state since the next signal that getty will receive, hopefully,
will be SIGUSR2. When SIGUSR1 is received, the user code must do the
following things:
1) Do fcloses on stdin, stdout, and stderr
2) Do closes on 0, 1, and 2
3) Delock the line
4) Update utmp:
a) Change LOGIN to DIALOUT
b) Change the type to a user process
5) I update wtmp even though SCO does not to keep a record of call outs
6) I then go into a pause state and wait for a "non-trapped" signal which
should be SIGUSR2
7) Just exit and let init spawn a new getty
The way ungetty knows that the getty is no longer active is by the change
to utmp.
The following is my interface code:
------------------------------ cut here ---------------------------------
int ungetty_call();
int ungetty_flag;
char Line[20];
main(argc,argv)
int argc;
char **argv;
{
/*
.................... initial .............................
................... getty code ...........................
*/
/* A SIGUSR1 is used to cause getty to start the ungetty handshaking */
if(signal(SIGUSR1, ungetty_call) == (int(*)())-1)
{
error("getty: Unable to interface with SIGUSR1!.\n");
exit(1);
}
/* More getty code */
}
/* In some inital subroutine, store the line name into the Line array
example: strcpy(Line, line);
*/
int
ungetty_call()
{
register int ownpid;
register struct utmp *u;
extern struct utmp *getutent(), *pututline();
register FILE *fp;
if(ungetty_flag) return; /* If unable to call uugetty, return back */
/* close the tty streams, 0, 1, and 2 */
fclose(stdin);
fclose(stdout);
fclose(stderr);
close(0);
close(1);
close(2);
delock(Line); /* Remove symbolic lock */
/* Look in "utmp" file for our own entry and change it to LOGIN. */
ownpid = getpid();
while ((u = getutent()) != NULL) {
/* Is this our own entry? */
/* Change utmp entry from LOGIN to DIALOUT and the type to a USER PROCESS */
/* UUGETTY LOOKS FOR THIS! */
if (u->ut_type == LOGIN_PROCESS && u->ut_pid == ownpid) {
strncpy(u->ut_line,Line,sizeof(u->ut_line));
strncpy(u->ut_user,"DIALOUT",sizeof(u->ut_user));
u->ut_type = USER_PROCESS;
/* Write out the updated entry. */
pututline(u);
break;
}
}
/* If we were successful in finding an entry for ourself in the */
/* utmp file, then attempt to append to the end of the wtmp file. */
/* I also write into /etc/wtmp to keep a log of the call outs. SCO does not
do this but they really should */
if (u != NULL && (fp = fopen(WTMP_FILE,"r+")) != NULL) {
fseek(fp,0L,2); /* Seek to end of file */
fwrite(u,sizeof(*u),1,fp);
fclose(fp);
}
/* Close the utmp file. */
endutent();
/* Pause until ungetty says it is ok! */
/* Instead of waiting for a SIGUSR2, I just go into a pause since the only
other signal your getty will receive is a SIGUSR2 <hopefully> */
(void)pause();
/* Just exit and init will spawn a new getty */
exit(0);
}
More information about the Comp.unix.xenix
mailing list