vntsd.c revision 8100efacfab0b6f34c0700fc9bf20aba0cc6ff93
/*
* 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 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* VNTSD main
*
* VNTSD takes the following options:
* -i <device instance>
* VCC device instance to use, e.g. virtual-console-concentrator@0.
* Required option.
* -p <ip address>
* IP address VNTSD listens to.
* -d
* Do not daemonize. This is only available in a DEBUG build.
* -t timeout for inactivity 0 = indefinite
*/
#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <thread.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <libintl.h>
#include <locale.h>
#include <syslog.h>
#include <netdb.h>
#include "vntsd.h"
#include "chars.h"
#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
#endif
/* global variables */
#ifdef DEBUG
int vntsddbg = 0x8;
#endif
#define MINUTE 60
#define LOCALHOST_IPv4 "127.0.0.1"
#define LOCALHOST_IPv6 "::1"
static void vntsd_exit(void);
/* Signal handler for SIGINT, SIGKILL and SIGHUP */
static void
exit_sig_handler(int sig)
{
/* not main thread, pass to main thread */
} else {
exit(0);
}
}
/*
* Before a thread reads in client's input, it attaches to vntsd timer so that
* it can be waken up if a client does not access the connection for
* VNTSD_INPUT_TIMEOUT(10) minutes.
*/
/* attach a thread to timer */
int
{
int rv;
return (VNTSD_SUCCESS);
}
return (rv);
}
/* detach a thread from timer */
int
{
int rv;
return (VNTSD_SUCCESS);
}
return (rv);
}
/* check threadd's timeout */
static boolean_t
{
/* wake up the thread */
}
/* return false to walk the queue */
return (B_FALSE);
}
/* reset timer */
static boolean_t
{
}
/* return false to walk the queue */
return (B_FALSE);
}
void
{
return;
}
(void*)tid);
}
/*
* When alarm goes off, wake up timeout threads. Alarm is set off every
* minutes.
*/
static void
{
static thread_t main_thread = 0;
return;
}
if (main_thread == 0) {
/* initialize thread id */
main_thread = thr_self();
} else if (main_thread != thr_self()) {
/* get signal because thread is timeout */
return;
}
/* in main thread */
/* wake up timeout threads */
/* reset alarm */
}
/* got a SIGUSER1 siginal */
static void
vntsd_sig_handler(int sig)
{
char err_msg[VNTSD_LINE_LEN];
sig);
}
}
/* vntsd exits */
static void
vntsd_exit(void)
{
/* cancel the timer */
(void) alarm(0);
}
/* delete all groups */
/* close control port */
/* clean up vntsdp */
closelog();
}
/*
* vntsd_help()
* print out valid command line options
*/
static void
vntsd_help(void)
{
"[-p <listen address>] [-t <timeout in minutes>]\n"));
}
/*
* get_listen_ip_addr()
* check for a valid control domain ip address in format of xxx.xxx.xxx.xxx.
* if ip address is valid and is assigned to this host, return ip address
* or else return VNTSD_INVALID_LISTEN_ADDR.
*/
static in_addr_t
get_listen_ip_addr(char *listen_addr)
{
char host_name[MAXPATHLEN];
int err;
struct sockaddr_in *sa;
return (VNTSD_INVALID_LISTEN_ADDR);
}
/* bad IP address format */
return (VNTSD_INVALID_LISTEN_ADDR);
if (err != 0) {
return (VNTSD_INVALID_LISTEN_ADDR);
}
/* LINTED E_BAD_PTR_CAST_ALIGN */
/* ip address found */
return (addr);
}
}
/* ip address not found */
return (VNTSD_INVALID_LISTEN_ADDR);
}
#ifdef DEBUG
#define DEBUG_OPTIONS "d"
#else
#define DEBUG_OPTIONS ""
#endif
int
{
char *path;
char *listen_addr = NULL;
int i;
int option;
int sz;
int fd;
int n;
/* internationalization */
(void) textdomain(TEXT_DOMAIN);
/* initialization */
/*
* ensure that we can obtain sufficient file descriptors for all
* the accept() calls when a machine contains many domains.
*/
"descriptor limit.");
exit(1);
}
NULL);
/* get CLI options */
switch (option) {
#ifdef DEBUG
case 'd':
break;
#endif
case 'i':
break;
case 'p':
break;
case 't':
if (n != 1) {
}
break;
default:
vntsd_help();
exit(1);
}
}
vntsd_help();
exit(1);
}
/* by default listen on loopback interface */
} else {
"Invalid listen address '%s'\n",
exit(2);
}
}
/* open VCC driver control port */
exit(1);
}
/* print error if device is not present */
"Error opening VCC device control port: %s",
path);
/* tell SMF no retry */
exit(2);
}
/* daemonize it */
if (pid < 0) {
perror("fork");
exit(1);
}
if (pid > 0) {
/* parent */
exit(0);
}
/*
* child process (daemon)
*
* Close all file descriptors other than 2 and the ctrl fd.
*/
(void) close(0);
(void) close(1);
(void) close(i);
}
/* obtain a new process group */
(void) setsid();
if (fd < 0) {
exit(1);
}
/* handle standard I/O */
exit(1);
}
exit(1);
}
/* ignore terminal signals */
}
/* set up signal handlers */
/* exit signals */
/* vntsd internal signals */
/* setup exit */
(void) atexit(vntsd_exit);
/* initialization */
/* set alarm */
}
/* get exiting consoles from vcc */
for (; ; ) {
/* poll vcc for configuration change */
/* wake up because a consle was deleted */
continue;
}
"vcc control poll err! aborting..");
exit(1);
}
/*
* Main thread may miss a console-delete signal when it is
* not polling vcc. check if any console is deleted.
*/
}
/*NOTREACHED*/
return (0);
}
/* export ip_addr */
struct in_addr
vntsd_ip_addr(void)
{
}
/*
* ioctl to vcc control port
* Supported ioctls interface are:
* ioctl code parameters return data
* VCC_NUM_CONSOLE none uint_t no consoles
* VCC_CONS_TBL none array of vcc_cons_t
* VCC_INQUIRY none vcc_response_t response
* VCC_CONS_INFO uint_t portno vcc_cons_t
* VCC_CONS_STATUS uint_t portno
* VCC_FORCE_CLOSE uint_t portno
*/
int
{
if ((ioctl_code == (VCC_CONS_INFO)) ||
(ioctl_code == (VCC_FORCE_CLOSE))) {
/* construct vcc in buf */
}
/* ioctl request error */
return (VNTSD_STATUS_VCC_IO_ERR);
}
return (VNTSD_SUCCESS);
}
/*
* check if a vcc i/o error is caused by removal of a console. If so
* wake up main thread to cleanup the console.
*/
int
{
/* console was deleted */
return (VNTSD_STATUS_VCC_IO_ERR);
}
if (vntsd_vcc_cons_alive(consp)) {
/* console is ok */
return (VNTSD_STATUS_CONTINUE);
}
/* console needs to be deleted */
/*
* main thread will close all clients after receiving console
* delete signal.
*/
/* mark the group */
/* signal main thread to deleted console */
return (VNTSD_STATUS_VCC_IO_ERR);
}