console.c revision 7636cb21f250f0485ca6052ffadc80ace93e6358
/*
* 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 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Listen thread creates a console thread whenever there is a tcp client
* made a conection to its port. In the console thread, if there are
* multiple consoles in the group, client will be asked for a console selection.
* a write thread for a console is created when first client connects to a
* selected console and console thread becomes read thread for the client.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <thread.h>
#include <synch.h>
#include <signal.h>
#include <assert.h>
#include <ctype.h>
#include <syslog.h>
#include <libintl.h>
#include <netdb.h>
#include "vntsd.h"
#include "chars.h"
/* display domain names in the group */
static boolean_t
{
char buf[VNTSD_LINE_LEN];
char *status;
} else {
}
}
/* output connected message to tcp client */
static int
char *domain_name)
{
int rv = VNTSD_SUCCESS;
char buf[VNTSD_LINE_LEN];
return (rv);
}
gettext("Connecting to console \"%s\" in group \"%s\" ...."),
return (rv);
}
gettext("Press ~? for control options .."))) !=
return (rv);
}
return (VNTSD_SUCCESS);
}
static int
{
/* create write thread for the console */
"create write thread failed\n",
return (VNTSD_ERR_CREATE_WR_THR);
}
return (VNTSD_SUCCESS);
}
/* Display all domain consoles in a group. */
static int
{
char vntsd_line[VNTSD_LINE_LEN];
int rv = VNTSD_SUCCESS;
!= VNTSD_SUCCESS) {
return (rv);
}
/*
* TRANSLATION_NOTE
* The following three strings of the form "DOMAIN .." are table
* headers and should be all uppercase.
*/
"%-20s%-30s%-25s",
gettext("DOMAIN STATE"));
return (rv);
}
}
return (rv);
}
/* display help */
static int
{
int rv = VNTSD_SUCCESS;
char *bufp;
!= VNTSD_SUCCESS) {
return (rv);
}
/*
* TRANSLATION_NOTE
* The following three strings of the form ". -- ..." are help
* messages for single character commands. Do not translate the
* character before the --.
*/
return (rv);
}
return (rv);
}
return (rv);
}
/*
* TRANSLATION_NOTE
* In the following string, "id" is a short mnemonic for
* "identifier" and both occurrences should be translated.
*/
" or domain {name}");
return (rv);
}
return (VNTSD_SUCCESS);
}
/* cons_by_name() - find a console structure according to a ldom's name */
static boolean_t
{
return (B_FALSE);
}
}
/* name_to_cons_no - convert a ldom's name to its consno */
static int
{
return (-1);
}
}
/* select a console to connect */
static int
vntsd_client_t *clientp, char c)
{
int cons_no = -1;
int n;
int i;
char buf[VNTSD_LINE_LEN];
int rv;
/* no console in this group */
return (VNTSD_STATUS_NO_CONS);
}
/* c{id} or n{name} */
n = VNTSD_LINE_LEN;
return (rv);
}
/* parse command */
for (i = 0; i < n; i++) {
switch (c) {
case 'c':
/* c{id} or c {id} */
continue;
}
return (VNTSD_ERR_INVALID_INPUT);
}
break;
case 'n':
/* n{name) or n {name} */
continue;
}
buf[n-1] = 0;
break;
default:
/* should never get here */
return (VNTSD_ERR_INVALID_INPUT);
}
/* got user selection */
break;
}
if (cons_no < 0) {
return (VNTSD_ERR_INVALID_INPUT);
}
/* get selected console */
/* during console selection, the console has been deleted */
return (VNTSD_ERR_INVALID_INPUT);
}
return (VNTSD_ERR_INVALID_INPUT);
}
return (VNTSD_SUCCESS);
}
/* compare if there is a match console in the gorup */
static boolean_t
{
if (consp_in_group == consp) {
return (B_TRUE);
} else {
return (B_FALSE);
}
}
/* connect a client to a console */
static int
{
/* check if console is valid */
return (VNTSD_STATUS_NO_CONS);
}
return (VNTSD_STATUS_NO_CONS);
}
/* enable daemon cmd */
/*
* the first connection to a console - a writer
* and the console has not opened.
*/
return (vntsd_vcc_err(consp));
}
}
/*
* move the client from group's no console selected queue
* to cons queue
*/
if (rv != VNTSD_SUCCESS) {
/* writer */
}
return (rv);
}
/* create a write thread */
if (rv != VNTSD_SUCCESS) {
return (rv);
}
}
/* write connecting message */
return (rv);
}
/* process input from client */
/* client disconnected from the console */
/* remove client from console queue */
/* append client to group's no console selected queue */
/* clean up console since there is no client connected to it */
/* force write thread to exit */
}
/* console is waiting for client to disconnect */
}
}
/* read command line input */
static int
{
int rv;
/* disable daemon special command */
!= VNTSD_SUCCESS) {
return (rv);
}
!= VNTSD_SUCCESS) {
return (rv);
}
return (rv);
}
return (VNTSD_SUCCESS);
}
return (rv);
}
/* reset client for selecting a console in the group */
static void
{
}
/* is there any connection to a given console? */
static boolean_t
{
has_client = B_TRUE;
return (has_client);
}
/*
* close one opened console.
* This function is passed to vntsd_que_walk to close one console.
* The function returns B_FALSE so that vntsd_que_walk will
* continue to apply the function to all consoles in the group.
*/
static boolean_t
{
}
return (B_FALSE);
}
/* clean up client and exit the thread */
static void
{
/* disconnct client from tcp port */
/*
* close all consoles in the group if the client is the
* last one connected to the group
*/
}
/* group is waiting to be deleted */
}
thr_exit(0);
}
/* check client's status. exit if client quits or fatal errors */
static void
{
char err_msg[VNTSD_LINE_LEN];
"client status=%x num consoles=%d \n",
/* no more console in the group */
}
if (status == VNTSD_STATUS_INTR) {
/* reason for signal? */
}
switch (status) {
case VNTSD_STATUS_CLIENT_QUIT:
return;
/* no other selection available */
} else {
}
return;
case VNTSD_STATUS_VCC_IO_ERR:
/* check if console was deleted */
}
if (status != VNTSD_STATUS_CONTINUE) {
/* console was deleted */
}
}
/* console is ok */
return;
/* same console */
return;
}
/* get selected console */
return;
case VNTSD_SUCCESS:
case VNTSD_STATUS_CONTINUE:
case VNTSD_STATUS_NO_CONS:
return;
case VNTSD_ERR_INVALID_INPUT:
return;
default:
/* fatal error */
return;
}
}
/* console thread */
void *
{
char buf[MAXHOSTNAMELEN];
char prompt[72];
char cmd;
int rv = VNTSD_SUCCESS;
int num_cons;
/* check if group is removed */
/* host name */
}
"%s-vnts-%s: h, l, c{id}, n{name}, q:",
/* long prompt doesn't fit, use short one */
"vnts: h, l, c{id}, n{name}, q:");
}
for (;;) {
cmd = ' ';
/* console to connect to */
/* check error and may exit */
}
switch (cmd) {
case 'l':
/* list domain names */
break;
case 'q':
break;
case ' ':
if (num_cons == 1) {
/* by pass selecting console */
consp = (vntsd_cons_t *)
} else {
continue;
}
} else {
}
/* connect to console */
break;
case 'c':
case 'n':
/* select console */
if (rv == VNTSD_ERR_INVALID_INPUT) {
break;
}
} else {
}
/* connect to console */
"connect_cons returns %d\n",
break;
case 'h':
default:
break;
}
/* check error and may exit */
}
/*NOTREACHED*/
return (NULL);
}