/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <termio.h>
#include <string.h>
#include <signal.h>
#include <poll.h>
#include <unistd.h>
#include <sys/resource.h>
#include "sac.h"
#include "ttymon.h"
#include "tmstruct.h"
#include "tmextern.h"
#ifdef SYS_NAME
#endif
static void openline();
static void invoke_service();
static char *do_autobaud();
static struct Gdef *next_speed();
static int check_hup();
/*
* tmchild - process that handles peeking data, determine baud rate
* and invoke service on each individual port.
*
*/
void
{
#ifdef DEBUG
debug("in tmchild");
#endif
exit(1);
}
/*
* the following check is to make sure no hangup
* happens before registering for SIGPOLL
*/
#ifdef DEBUG
debug("PCpipe hungup, tmchild exiting");
#endif
exit(1);
}
}
}
/*
* become the session leader so that a controlling tty
* will be allocated.
*/
(void) setsid();
}
return;
}
}
}
}
(State != PM_DISABLED) &&
/*
* if "c" flag is set, and the port is not disabled
* invoke service immediately
*/
log("set final termio failed");
exit(1);
}
}
}
log("set final termio failed");
exit(1);
}
}
}
/* Loop until user is successful in invoking service. */
for (;;) {
/* Peek the user's typed response and respond appropriately. */
switch (poll_data()) {
case GOODNAME:
#ifdef DEBUG
debug("got GOODNAME");
#endif
(void) alarm((unsigned)0);
}
break;
}
log("set final termio failed");
exit(1);
}
case BADSPEED:
/* wrong speed! try next speed in the list. */
#ifdef DEBUG
debug("BADSPEED: setup next speed");
#endif
if (auto_termio(0) == -1) {
exit(1);
}
}
else {
auto_speed = NULL;
/*
* this reset may fail if the speed is not
* supported by the system
* we just cycle through it to the next one
*/
log("Warning -- speed of <%s> may "
"be not supported by the system",
}
}
break;
case NONAME:
#ifdef DEBUG
debug("got NONAME");
#endif
break;
} /* end switch */
}
} /* end for loop */
}
static void
{
int rtn = 0;
int line_count;
#ifdef DEBUG
debug("in openline");
#endif
(void) close(0);
/* open should return fd 0, if not, then close it */
exit(1);
}
}
(void) close(1);
(void) close(2);
(void) dup(0);
(void) dup(0);
/*
* - wait for "p_count" lines
* - datakit switch does not
* know you are a host or a terminal
* - so it send you several lines of msg
* - we need to swallow that msg
* - we assume the baud rate is correct
* - if it is not, '\n' will not look like '\n'
* and we will wait forever here
*/
log("set final termio failed");
exit(1);
}
|| *buffer == '\0'
|| *buffer == '\004') {
(void) close(0);
exit(0);
}
if (*buffer == '\n')
line_count++;
}
}
else { /* wait for 1 char */
log("set termio RAW failed");
exit(1);
}
} else
/*
* NOTE: Cu on a direct line when ~. is encountered will
* send EOTs to the other side. EOT=\004
*/
(void) close(0);
exit(0);
}
}
log("set final termio failed");
exit(1);
}
}
}
/* set advisory lock on the line */
if (tm_lock(0) != 0) {
/*
* device is locked
* child exits and let the parent wait for
* the lock to go away
*/
exit(0);
}
/* change ownership back to root */
(void) fchmod(0, 0620);
}
return;
}
/*
* write_prompt - write the msg to fd
* - if flush is set, flush input queue
* - if clear is set, write a new line
*/
void
int fd;
{
#ifdef DEBUG
debug("in write_prompt");
#endif
if (flush)
if (clear) {
}
#ifdef SYS_NAME
#endif
else
}
/*
* timedout - input period timed out
*/
void
timedout()
{
exit(1);
}
#ifdef SYS_NAME
/*
* void sys_name() - generate a msg with system id
*/
void
int fd;
{
#if 0 /* 1111333 - don't print node name, we already do this elsewhere */
}
#endif
}
}
}
#endif
/*
* do_autobaud - do autobaud
* - if it succeed, set the new speed and return
* - if it failed, it will get the nextlabel
* - if next entry is also autobaud,
* it will loop back to do autobaud again
* - otherwise, it will set new termio and return
*/
static char *
{
char *auto_speed;
#ifdef DEBUG
debug("in do_autobaud");
#endif
while (!done) {
continue;
}
else {
exit(1);
}
}
}
else {
exit(1);
}
}
}
#ifdef DEBUG
debug("autobaud done");
#endif
return (auto_speed);
}
/*
* next_speed(speedef)
* - find the next entry according to nextlabel. If "nextlabel"
* is not valid, go back to the old ttylabel.
*/
static struct Gdef *
{
return (speedef);
/* go back to the original entry. */
/* if failed, complain and quit. */
exit(1);
}
}
return (sp);
}
/*
* inform_parent() - inform ttymon that tmchild is going to exec service
*/
static void
int fd;
{
}
/*
* void invoke_service - invoke the service
*/
static void
{
int i, fd;
#ifdef DEBUG
debug("in invoke_service");
#endif
cons_printf("Warning -- ttymon cannot allocate controlling "
cons_printf("\tThere may be another session active on this "
"port.\n");
/*
* if not on console, write to stderr to warn the user
* also.
*/
"allocate controlling tty on \"%s\",\n",
"active on this port.\n");
}
}
}
log("invoke_service: account failed");
exit(1);
}
}
/* parse command line */
exit(1);
}
}
exit(1);
}
#ifdef DEBUG
debug("about to run config script");
#endif
if (i < 0) {
log("doconfig failed, system error");
}
else {
log("doconfig failed on line %d of script %s",
}
exit(1);
}
}
exit(1);
}
exit(1);
}
exit(1);
}
/* change ownership and mode of device */
(void) fchmod(0, 0620);
}
exit(1);
}
/* invoke the service */
}
exit(1);
}
}
/* restore signal handlers and mask */
#ifdef DEBUG
#endif
/* exec returns only on failure! */
exit(1);
}
/*
* check_hup(fd) - do a poll on fd to check if it is in hangup state
* - return 1 if hangup, otherwise return 0
*/
static int
int fd;
{
int ret;
for (;;) {
if (ret < 0) {
continue;
exit(1);
}
else if (ret > 0) {
return (1);
}
}
return (0);
}
}
/*
* sigpoll() - SIGPOLL handle for tmchild
* - when SIGPOLL is received by tmchild,
* the pipe between ttymon and tmchild is broken.
* Something must happen to ttymon.
*/
void
sigpoll()
{
#ifdef DEBUG
debug("tmchild got SIGPOLL, exiting");
#endif
exit(1);
}