sandy@conexch.UUCP (Sandford Zelkovitz) (06/28/89)
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); }