872 lines
22 KiB
C
872 lines
22 KiB
C
static char sccsid[] = "@(#)64 1.32 src/bos/usr/lib/methods/common/findcons.c, sysxcons, bos411, 9428A410j 94/07/01 17:11:01";
|
|
/*
|
|
* COMPONENT_NAME: (CFGMETHODS) System Configuration Console Finder
|
|
*
|
|
* FUNCTIONS: MSGSTR
|
|
* dstruct
|
|
* findcons
|
|
* freeall
|
|
* get_disp_devs
|
|
* get_num_lfts
|
|
* poll_displays
|
|
* setterm
|
|
* write_lft_prompt
|
|
* write_prompts
|
|
*
|
|
*
|
|
* ORIGINS: 27
|
|
*
|
|
* IBM CONFIDENTIAL -- (IBM Confidential Restricted when
|
|
* combined with the aggregated modules for this product)
|
|
* SOURCE MATERIALS
|
|
*
|
|
* (C) COPYRIGHT International Business Machines Corp. 1989, 1994
|
|
* All Rights Reserved
|
|
* US Government Users Restricted Rights - Use, duplication or
|
|
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
|
*/
|
|
|
|
/*
|
|
* NAME: findcons
|
|
*
|
|
* FUNCTION:
|
|
* This subroutine queries all display devices to determine
|
|
* which one will be the default for output and input during the
|
|
* installation process. It does this by displaying a message on
|
|
* each terminal device and polling each until one responds.
|
|
*
|
|
* EXECUTION ENVIRONMENT:
|
|
*
|
|
* The findcons subroutine is called from the
|
|
* console config routine.
|
|
*
|
|
*/
|
|
|
|
#define _KERNSYS
|
|
#define _RSPC
|
|
#include <sys/systemcfg.h>
|
|
#undef _RSPC
|
|
#undef _KERNSYS
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <sys/lft_ioctl.h>
|
|
#include <sys/errno.h>
|
|
#include <termio.h>
|
|
#include <termios.h>
|
|
#include <fcntl.h>
|
|
#include <sys/signal.h>
|
|
#include <nl_types.h>
|
|
#include <odmi.h>
|
|
#include <sys/cfgodm.h>
|
|
#include <sys/cfgdb.h>
|
|
#include <sys/mdio.h>
|
|
|
|
#include "console_msg.h"
|
|
extern nl_catd catd;
|
|
#define MSGSTR(Num, Str) catgets(catd, MS_CONSOLE, Num, Str)
|
|
|
|
/* system keylock defines */
|
|
#define KEYMASK 0x00000003
|
|
#define SECURE 1
|
|
#define SERVICE 2
|
|
#define NORMAL 3
|
|
/* servmode flag defines */
|
|
#define SERVMODE 0x1 /* system in SERVICE mode flag */
|
|
#define CONSDEFINED 0x2 /* console is currently defined */
|
|
|
|
#define MAX_LFTS 12 /* Max supported physical displays (F1-F12) */
|
|
int num_lfts; /* contains the total number of lft's */
|
|
|
|
extern int setleds();
|
|
extern int servmode; /* service mode flag from cfgcon */
|
|
int term_choice; /* terminal number chosen as console */
|
|
|
|
char console_physdisp[16]=""; /* console physical display name */
|
|
struct {
|
|
char name[16];
|
|
} physdisp_lft[MAX_LFTS]; /* names of lft displays */
|
|
char console_path[32]=""; /* pathname of default console device */
|
|
int runtime; /* runtime execution mode for LIC prompt */
|
|
|
|
/*
|
|
The following structure is a doubly linked list that will contain
|
|
the device name of all tty's and lft displays on the system.
|
|
*/
|
|
|
|
struct terminals {
|
|
int fd; /* file descriptor to open device */
|
|
char dispdev[16]; /* device name of tty/lft */
|
|
struct terminals *next; /* pointer to next struct */
|
|
struct terminals *last; /* pointer to last struct */
|
|
} *topterm;
|
|
|
|
char * getenv();
|
|
|
|
int totdisps; /* Total number of displays */
|
|
char strbuf[800];
|
|
|
|
/*
|
|
* findcons():
|
|
* Open all available tty/lft devices
|
|
* Write message to all tty/lft devices
|
|
* Wait for input from any tty/lft device
|
|
* Copy pathname of chosen device to console_path
|
|
* If lft responded, copy physical display id to console_physdisp
|
|
*/
|
|
int
|
|
findcons()
|
|
{
|
|
int fildes; /* file descriptor of standard out */
|
|
int count; /* loop index */
|
|
int retcode = 0; /* return value of findcons */
|
|
int rc; /* intermediate return values */
|
|
int default_lft; /* the number associated with lft */
|
|
struct PdAt *pdatp; /* pointer to Predefined */
|
|
struct terminals *curterm; /* used to traverse linked list */
|
|
struct listinfo stat_info;
|
|
char crit[128];
|
|
|
|
/* check on RUNTIME flag */
|
|
sprintf(crit,PHASE1_DISALLOWED);
|
|
pdatp = (struct PdAt *)odm_get_list(PdAt_CLASS,crit,&stat_info,1,1);
|
|
if (((int)pdatp != -1) && ((int)pdatp != NULL))
|
|
runtime = TRUE;
|
|
else
|
|
runtime = FALSE;
|
|
|
|
/* Determine the total number of lft displays available. */
|
|
num_lfts = get_num_lfts();
|
|
|
|
/* Construct a linked list of all available display devices. */
|
|
retcode = get_disp_devs();
|
|
|
|
#ifdef _DEBUG
|
|
dstruct(topterm);
|
|
#endif
|
|
|
|
/* Traverse the linked list of terminal names, write a prompt. */
|
|
if (retcode == 0)
|
|
retcode = write_prompts();
|
|
|
|
/* Poll input from all display devices. */
|
|
if ((retcode == 0) && (servmode != -1))
|
|
poll_displays();
|
|
|
|
/* Close all terminals and get ready to get out of here */
|
|
for(curterm = topterm;curterm != NULL; curterm = curterm->next)
|
|
close(curterm->fd);
|
|
|
|
/* Free all of the nodes in the linked list. */
|
|
freeall(topterm);
|
|
|
|
return ( retcode );
|
|
} /* findcons */
|
|
|
|
|
|
|
|
/*
|
|
freeall() is a recursive function which frees all of the nodes of a linked
|
|
list by recursively traversing the list to the end and then by
|
|
freeing the nodes from the end backwards.
|
|
*/
|
|
|
|
freeall(top)
|
|
struct terminals *top;
|
|
{
|
|
#ifdef _DEBUG
|
|
printf("freeall\n");
|
|
#endif
|
|
if ( top != NULL )
|
|
{
|
|
freeall(top->next);
|
|
free(top);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
get_disp_devs: Constructs a linked list of available display devices.
|
|
*/
|
|
|
|
int
|
|
get_disp_devs()
|
|
{
|
|
struct terminals *curterm, *nexterm; /* used to create linked list */
|
|
struct CuDv cudv; /* Pointer to query results */
|
|
struct CuAt *cuatp; /* Pointer to query results */
|
|
struct objlistinfo cuat_info,cudv_cinfo; /* Results of search stats */
|
|
int rc;
|
|
int i;
|
|
char tbuf[80]; /* Temp buffer to build args */
|
|
|
|
#ifdef _DEBUG
|
|
printf("get_disp_devs\n");
|
|
#endif
|
|
|
|
topterm = NULL; /* No list yet set top to NULL */
|
|
|
|
/* initialize ODM */
|
|
|
|
odm_initialize();
|
|
|
|
if (num_lfts) /* were any found in get_num_lfts? */
|
|
{
|
|
/* look for an lft defined in the database */
|
|
rc = odm_get_first(CuDv_CLASS, "name = 'lft0'", &cudv);
|
|
if ( rc < 0 )
|
|
{
|
|
fprintf(stderr,MSGSTR(CFCONE01,"cfgcon: failure accessing the device database (ODM) \n"));
|
|
return(4);
|
|
}
|
|
|
|
/* LFT found on system. */
|
|
if ((rc > 0) && (cudv.status == AVAILABLE))
|
|
{
|
|
nexterm = (struct terminals *) malloc(sizeof(
|
|
struct terminals));
|
|
|
|
if ( nexterm == NULL )
|
|
{
|
|
fprintf(stderr,MSGSTR(CFCONE07,"cfgcon: a system failure has occurred (malloc failure) \n"));
|
|
return(4);
|
|
}
|
|
|
|
if ( topterm == NULL ) /* First record in the chain */
|
|
{
|
|
topterm = nexterm; /* Point topterm to chain */
|
|
nexterm->last = NULL; /* Set top of chain pointer */
|
|
}
|
|
else
|
|
{
|
|
curterm->next = nexterm; /* Set pointer to last */
|
|
nexterm->last = curterm; /* Set pointer to next */
|
|
}
|
|
|
|
/*
|
|
Make new record current, put lft onto the list and
|
|
ensure last is NULL.
|
|
*/
|
|
curterm = nexterm;
|
|
strcpy(curterm->dispdev, "lft0");
|
|
curterm->next = NULL;
|
|
|
|
}
|
|
}
|
|
|
|
/*
|
|
Check ODM database for "altcons" attributes. Check if these
|
|
devices are AVAILABLE, if so then include
|
|
it in the list of candidates.
|
|
*/
|
|
|
|
cuatp = (struct CuAt *)odm_get_list( CuAt_CLASS,
|
|
"name = 'sys0' and attribute = 'altcons'",
|
|
&cuat_info,1,1);
|
|
if (cuatp == (struct CuAt *) -1)
|
|
{
|
|
fprintf(stderr,MSGSTR(CFCONE01,"cfgcon: failure accessing the device database (ODM) \n"));
|
|
return(4);
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
printf("cuat_info.num = %d\n", cuat_info.num);
|
|
#endif
|
|
/*
|
|
For all the ttys for whom "altcons" attribute is set, check
|
|
if the device is avilable then add it to the list.
|
|
Remove the "altcons" attribute from the database.
|
|
*/
|
|
|
|
for( i = 1; i <= cuat_info.num; i++ )
|
|
{
|
|
sprintf(tbuf, "name = '%s'",
|
|
cuatp->value);
|
|
cuatp++;
|
|
#ifdef _DEBUG
|
|
printf("criteria = %s\n", tbuf);
|
|
|
|
#endif
|
|
|
|
rc = odm_get_first(CuDv_CLASS, tbuf, &cudv);
|
|
if ( rc < 0 )
|
|
{
|
|
fprintf(stderr,MSGSTR(CFCONE01,"cfgcon: failure accessing the device database (ODM) \n"));
|
|
return(4);
|
|
}
|
|
|
|
/* tty was found on current serial adapter. */
|
|
|
|
if ( rc != NULL && cudv.status == AVAILABLE)
|
|
{
|
|
nexterm = (struct terminals *) malloc(sizeof
|
|
(struct terminals));
|
|
if (nexterm == NULL)
|
|
{
|
|
fprintf(stderr, "malloc failed.\n");
|
|
return(5);
|
|
}
|
|
|
|
if(topterm == NULL)
|
|
{
|
|
topterm = nexterm;
|
|
nexterm->last = NULL;
|
|
}
|
|
else
|
|
{
|
|
curterm->next = nexterm;
|
|
nexterm->last = curterm;
|
|
}
|
|
|
|
curterm = nexterm;
|
|
strcpy(curterm->dispdev, cudv.name);
|
|
curterm->next = NULL;
|
|
#ifdef _DEBUG
|
|
printf("cudv->name = %s\n", cudv.name);
|
|
#endif
|
|
/* Remove this attribute from the CuAt db*/
|
|
sprintf(tbuf,
|
|
"name = 'sys0' AND attribute = 'altcons' AND value = '%s'", cudv.name);
|
|
|
|
if (odm_rm_obj(CuAt_CLASS, tbuf) < 0) {
|
|
fprintf(stderr,MSGSTR(CFCONE01,"cfgcon: failure accessing the device database (ODM) \n"));
|
|
return(6);
|
|
}
|
|
}
|
|
|
|
} /* for */
|
|
|
|
/* All done with odm */
|
|
odm_terminate();
|
|
return (0);
|
|
}
|
|
|
|
|
|
/*
|
|
get_num_lfts: query lft and return number of lft displays attached.
|
|
*/
|
|
get_num_lfts()
|
|
{
|
|
int i, fd, rc;
|
|
int num=0;
|
|
lft_query_t lftq;
|
|
lft_disp_query_t lftdq;
|
|
lft_disp_info_t lft_disps[MAX_LFTS];
|
|
|
|
setsid();
|
|
if( (fd = open("/dev/lft0", O_RDWR | O_NDELAY)) > 0 )
|
|
{
|
|
rc = ioctl(fd, LFT_QUERY_LFT, &lftq);
|
|
if (rc) {
|
|
#ifdef _DEBUG
|
|
fprintf(stderr,
|
|
"ioctl LFT_QUERY_LFT failed with return code %d and errno %d\n",
|
|
rc, errno);
|
|
#endif
|
|
close(fd);
|
|
return(num);
|
|
}
|
|
num = (lftq.number_of_displays > MAX_LFTS) ?
|
|
MAX_LFTS : lftq.number_of_displays;
|
|
}
|
|
else
|
|
{
|
|
#ifdef _DEBUG
|
|
fprintf(stderr,
|
|
"open of /dev/lft0 failed with error %d\n", errno);
|
|
#endif
|
|
return(num);
|
|
}
|
|
|
|
if (num)
|
|
{
|
|
/*
|
|
There is an lft, so fill the physdisp_lft[] array with all
|
|
of the physical display names of the attached lft displays.
|
|
*/
|
|
lftdq.num_of_disps = num;
|
|
lftdq.lft_disp = &lft_disps[0];
|
|
rc = ioctl(fd, LFT_QUERY_DISP, &lftdq);
|
|
if (rc)
|
|
{
|
|
#ifdef _DEBUG
|
|
fprintf(stderr,
|
|
"ioctl LFT_QUERY_DISP failed with rc %d and errno %d\n",
|
|
rc, errno);
|
|
#endif
|
|
close(fd);
|
|
return(0);
|
|
}
|
|
for (i=0; i<num; i++)
|
|
strcpy(physdisp_lft[i].name,
|
|
lft_disps[i].disp_name);
|
|
}
|
|
close(fd);
|
|
#ifdef _DEBUG
|
|
printf("number of lft's = %d\n", num);
|
|
for (i=0; i<num; i++)
|
|
printf("display %d name: %s\n", i, physdisp_lft[i].name);
|
|
#endif
|
|
return(num);
|
|
}
|
|
|
|
|
|
/*
|
|
poll_displays: Read from all terminal devices. When one returns input,
|
|
assign pointer to that device name and break.
|
|
*/
|
|
int
|
|
poll_displays()
|
|
{
|
|
char *format;
|
|
char fbuf[3]; /* function key buffer */
|
|
int notdone; /* binary flag to specify end of loop */
|
|
int rc;
|
|
int i, j, tty_choice;
|
|
int timeout = 30; /* 30 second timeout for console select*/
|
|
MACH_DD_IO mddRecord;
|
|
ulong currkey, startkey;
|
|
int fdmdd = -1; /* file descriptor for /dev/nvram */
|
|
|
|
struct terminals *curterm;
|
|
char *clear_screen = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
|
|
char *lic1prompt, *lic2prompt;
|
|
|
|
lic1prompt = MSGSTR(CFGCLIC1,"\n\r HARDWARE SYSTEM MICROCODE\n\r Licensed Internal Code - Property of IBM \n\r (C) Copyright IBM Corp. 1990, 1994.\n\r All rights reserved.\n\n\r US Government Users Restricted Rights -");
|
|
|
|
lic2prompt = MSGSTR(CFGCLIC2,"\n\r Use, duplication or disclosure restricted\n\r by GSA ADP Schedule Contract with IBM Corp.\n\n\n\r");
|
|
|
|
#ifdef _DEBUG
|
|
printf("poll_displays\n");
|
|
printf("service mode = %d \n",servmode);
|
|
#endif
|
|
notdone = TRUE;
|
|
setleds (0xA31);
|
|
/* if service mode then open bus driver to sense position of keylock */
|
|
if (servmode & SERVMODE)
|
|
if ((fdmdd = open("/dev/nvram", O_RDONLY)) != -1)
|
|
{
|
|
mddRecord.md_incr = MV_WORD;
|
|
mddRecord.md_size = 1;
|
|
mddRecord.md_data = (uchar *)&startkey;
|
|
#ifdef _DEBUG
|
|
printf("nvram device open successful \n");
|
|
#endif
|
|
if (ioctl(fdmdd, MIOGETKEY, &mddRecord) == -1)
|
|
{
|
|
/* ioctl() failed */
|
|
#ifdef _DEBUG
|
|
printf("MIOGETKEY ioctl failed\n");
|
|
#endif
|
|
close(fdmdd);
|
|
fdmdd = -1;
|
|
}
|
|
else
|
|
{
|
|
#ifdef _DEBUG
|
|
printf("start key position = %d \n", startkey);
|
|
#endif
|
|
startkey &= KEYMASK;
|
|
}
|
|
}
|
|
|
|
if (num_lfts == 0)
|
|
tty_choice = 1;
|
|
else
|
|
tty_choice = num_lfts;
|
|
|
|
while ( notdone )
|
|
{
|
|
/* if we were in service mode at boot time and the current
|
|
keylock switch position has been changed while we were
|
|
polling for displays, then set no console flag and
|
|
exit loop
|
|
*/
|
|
if (fdmdd != -1)
|
|
{
|
|
mddRecord.md_incr = MV_WORD;
|
|
mddRecord.md_size = 1;
|
|
mddRecord.md_data = (uchar *)&currkey;
|
|
if ((ioctl(fdmdd, MIOGETKEY, &mddRecord) != -1))
|
|
{
|
|
currkey &= KEYMASK;
|
|
if (currkey != startkey)
|
|
{
|
|
#ifdef _DEBUG
|
|
printf("key position changed \n");
|
|
#endif
|
|
setleds (0xA34);
|
|
servmode = -1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
for( curterm = topterm, i = tty_choice;
|
|
curterm != NULL && notdone;
|
|
curterm = curterm->next, i++ )
|
|
{
|
|
strbuf[0] = '\0';
|
|
rc = read( curterm->fd, strbuf, 79);
|
|
if (rc > 0 && strbuf[0] != '\n')
|
|
{
|
|
strbuf[rc] = '\0';
|
|
#ifdef _DEBUG
|
|
{
|
|
char *ptr;
|
|
ptr = strbuf;
|
|
while(*ptr)
|
|
printf(" %02x",*ptr++);
|
|
}
|
|
#endif
|
|
if (strcmp(curterm->dispdev, "lft0") == 0)
|
|
{
|
|
if ((sscanf(strbuf,
|
|
"\033[%dq",&term_choice)==1)
|
|
&& (term_choice >0) &&
|
|
(term_choice <= num_lfts))
|
|
{
|
|
#ifdef _DEBUG
|
|
printf("lft term_choice = %d\n", term_choice);
|
|
#endif
|
|
notdone = FALSE;
|
|
strcpy(console_physdisp,
|
|
physdisp_lft[term_choice-1].name);
|
|
strcpy(console_path,
|
|
curterm->dispdev);
|
|
}
|
|
}
|
|
else /* async terminal */
|
|
{
|
|
for (j = 0 ; j < 79; j++)
|
|
if (strbuf[j] < '0' ||
|
|
strbuf[j] > '9')
|
|
{
|
|
strbuf[j] = '\0';
|
|
break;
|
|
}
|
|
term_choice = atoi(strbuf);
|
|
if (term_choice == i)
|
|
{
|
|
#ifdef _DEBUG
|
|
printf("tty term_choice = %d\n", term_choice);
|
|
#endif
|
|
notdone = FALSE;
|
|
strcpy(console_path,
|
|
curterm->dispdev);
|
|
/* turn echo on for maintenance shell */
|
|
setterm(curterm->fd,
|
|
ECHO);
|
|
}
|
|
}
|
|
}
|
|
#ifdef _DEBUG else
|
|
if (rc == -1) {
|
|
printf("read %d failed with errno %d\n",
|
|
curterm->fd, errno);
|
|
notdone = FALSE; /* exit now */
|
|
}
|
|
#endif
|
|
} /* end of for all terminals */
|
|
|
|
/* if all terminals have been polled then sleep for 1 second before
|
|
repolling. If console defined then only poll for timeout times and the
|
|
let the system continue by setting a -1 in servmode and exiting
|
|
*/
|
|
if (notdone == TRUE)
|
|
{
|
|
sleep(1); /* sleep for 1 second before looping */
|
|
if (((--timeout)== 0) && (servmode & CONSDEFINED)
|
|
&& !(servmode & SERVMODE))
|
|
{
|
|
servmode = -1;
|
|
notdone = FALSE;
|
|
setleds (0xA34);
|
|
}
|
|
}
|
|
|
|
} /* end of while not done*/
|
|
|
|
if (fdmdd != -1)
|
|
close(fdmdd);
|
|
|
|
/* clear the messages from screens */
|
|
for( curterm = topterm; curterm != NULL;
|
|
curterm = curterm->next)
|
|
{
|
|
tcflush(curterm->fd, TCIOFLUSH);
|
|
if (strcmp(curterm->dispdev, "lft0") == 0)
|
|
{
|
|
for ( i = 0; i < num_lfts; i++ )
|
|
{
|
|
ioctl(curterm->fd,
|
|
LFT_SET_DFLT_DISP,
|
|
physdisp_lft[i].name);
|
|
WriteTO(curterm->fd, clear_screen, 25);
|
|
|
|
/* put out Licensed Microcode Copyright if not runtime */
|
|
/* only write to selected display */
|
|
if ((runtime == FALSE) &&
|
|
(!(__rspc())) &&
|
|
(strcmp(physdisp_lft[i].name,
|
|
console_physdisp) == 0))
|
|
{
|
|
rc = WriteTO (curterm->fd,lic1prompt,
|
|
strlen(lic1prompt));
|
|
rc = WriteTO (curterm->fd,lic2prompt,
|
|
strlen(lic2prompt));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WriteTO(curterm->fd, clear_screen, 25);
|
|
|
|
/* put out Licensed Microcode Copyright if not runtime */
|
|
/* only write to selected display */
|
|
if ((runtime == FALSE) &&
|
|
(!(__rspc())) &&
|
|
(strcmp(curterm->dispdev, console_path) == 0))
|
|
{
|
|
rc = WriteTO (curterm->fd,lic1prompt,
|
|
strlen(lic1prompt));
|
|
rc = WriteTO (curterm->fd,lic2prompt,
|
|
strlen(lic2prompt));
|
|
}
|
|
}
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
write_prompts: Traverse the linked list of terminal names, write a prompt.
|
|
*/
|
|
int
|
|
write_prompts()
|
|
{
|
|
|
|
char *ttyprompt;
|
|
int rc;
|
|
int fildes;
|
|
struct terminals *curterm;
|
|
FILE *fptr;
|
|
int rc1;
|
|
|
|
#ifdef _DEBUG
|
|
printf("write_prompts\n");
|
|
#endif
|
|
|
|
totdisps = 0;
|
|
|
|
|
|
ttyprompt = MSGSTR(CFGCTTY,"\n\n\
|
|
\r ******* Please define the System Console. *******\n\n\r\
|
|
Type a %d and press Enter to use this terminal as the\n\
|
|
system console.\n\
|
|
Typ een %d en druk op Enter om deze terminal als de\n\
|
|
systeemconsole to gebruiken.\n\
|
|
Skriv tallet %d og trykk paa Enter for aa bruke denne\n\
|
|
terminalen som systemkonsoll.\n\
|
|
Pour definir ce terminal comme console systeme, appuyez\n\
|
|
sur %d puis sur Entree.\n\
|
|
Taste %d und anschliessend die Eingabetaste druecken, um\n\
|
|
diese Datenstation als Systemkonsole zu verwenden.\n\
|
|
Premere il tasto %d ed Invio per usare questo terminal\n\
|
|
come console.\n\
|
|
Escriba %d y pulse Intro para utilizar esta terminal como\n\
|
|
consola del sistema.\n\
|
|
Tryck paa %d och sedan paa Enter om du vill att den haer\n\
|
|
terminalen ska vara systemkonsol.\n\n\n\n\n");
|
|
|
|
for(curterm = topterm; curterm != NULL; curterm = curterm->next)
|
|
{
|
|
sprintf(strbuf, "/dev/%s", curterm->dispdev);
|
|
if( (curterm->fd = open(strbuf, O_RDWR|O_NDELAY) ) < 0)
|
|
{
|
|
/* If can't open, then drop from the list */
|
|
#ifdef _DEBUG
|
|
printf("open of %s failed with rc %d and errno %d\n", curterm->dispdev,
|
|
curterm->fd, errno);
|
|
#endif
|
|
if( curterm->last != NULL )
|
|
(curterm->last)->next = curterm->next;
|
|
else
|
|
topterm = curterm->next;
|
|
if(curterm->next != NULL)
|
|
(curterm->next)->last = curterm->last;
|
|
free(curterm);
|
|
continue;
|
|
}
|
|
|
|
if( ((strcmp(curterm->dispdev, "lft0") == 0)) )
|
|
{
|
|
setterm(curterm->fd, ECHO);
|
|
write_lft_prompt(curterm->fd);
|
|
}
|
|
else /* must be tty */
|
|
{
|
|
/* output message to press enter */
|
|
setterm(curterm->fd,0); /* no echo */
|
|
sleep(1); /* wait for slow terminals */
|
|
++totdisps;
|
|
sprintf(strbuf, ttyprompt, totdisps,totdisps,
|
|
totdisps,totdisps,totdisps,totdisps,
|
|
totdisps,totdisps);
|
|
rc = WriteTO (curterm->fd, strbuf,
|
|
strlen(strbuf));
|
|
}
|
|
#ifdef _DEBUG
|
|
printf("strbuf = %s\n", strbuf);
|
|
dstruct(curterm);
|
|
#endif
|
|
} /* end for */
|
|
|
|
if( totdisps == 0 )
|
|
{
|
|
fprintf(stderr,MSGSTR(CFCONE06,"cfgcon: console is not defined and no candidate terminals were detected \n"));
|
|
servmode = -1; /* indicate no terminals found */
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
/*
|
|
write_lft_prompt: output prompt to all lft displays.
|
|
*/
|
|
int
|
|
write_lft_prompt( int fildes)
|
|
{
|
|
char *lftprompt;
|
|
int count;
|
|
int rc;
|
|
|
|
|
|
#ifdef _DEBUG
|
|
printf("write_lft_prompt\n");
|
|
#endif
|
|
|
|
for( count = 0; count < num_lfts; count++)
|
|
{
|
|
#ifdef _DEBUG
|
|
printf("count=%d set default display=%s\n",
|
|
count,physdisp_lft[count].name);
|
|
#endif
|
|
if( ( rc = ioctl(fildes, LFT_SET_DFLT_DISP,
|
|
physdisp_lft[count].name )) < 0 )
|
|
{
|
|
fprintf(stderr,MSGSTR(CFCONE04,"cfgcon: failed to set physical display on LFT \n"));
|
|
continue;
|
|
}
|
|
lftprompt = MSGSTR(CFGCHFT," \n\n\r ******* Please define the System Console. *******");
|
|
rc = WriteTO (fildes, lftprompt, strlen(lftprompt));
|
|
#ifdef _DEBUG
|
|
if (rc < 0)
|
|
printf("write(%d, %s, %d) failed with errno %d\n",
|
|
fildes, lftprompt, strlen(lftprompt), errno);
|
|
#endif
|
|
lftprompt = MSGSTR(CFGCHFT1,"\n\n\
|
|
Type the F%d key and press Enter to use this display as\n\
|
|
the system console.\n\
|
|
Druk op de toets F%d en daarna op Enter om dit\n\
|
|
beeldstation als de systeemconsole te gebruiken.\n\
|
|
Trykk paa tasten F%d og deretter paa Enter for aa bruke\n\
|
|
denne skjermen som systemkonsoll.\n\
|
|
Pour definir ce terminal comme console systeme, appuyez\n\
|
|
sur la touche F%d puis sur Entree.\n\
|
|
Taste F%d und anschliessend die Eingabetaste druecken,\n\
|
|
um diese Anzeige als Systemkonsole zu verwenden.\n\
|
|
Premere il tasto F%d ed Invio per usare questo terminale\n\
|
|
come console per il sistema.\n\
|
|
Pulse la tecla F%d y pulse Intro para utilizar esta\n\
|
|
pantalla como consola del sistema.\n\
|
|
Tryck paa F%d och sedan paa Enter om du vill att den haer\n\
|
|
skaermen ska vara systemkonsol.\n\n\n");
|
|
++totdisps;
|
|
sprintf(strbuf, lftprompt, totdisps,totdisps,totdisps,
|
|
totdisps,totdisps,totdisps,totdisps,totdisps);
|
|
rc = WriteTO (fildes, strbuf, strlen(strbuf));
|
|
lftprompt =MSGSTR(CFGCHFT2,"");
|
|
rc = WriteTO (fildes, lftprompt, strlen(lftprompt));
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
/*
|
|
setterm: setup terminal for input/output
|
|
*/
|
|
|
|
int
|
|
setterm( int fd , int flag)
|
|
{
|
|
struct termios tt;
|
|
|
|
tcgetattr(fd, &tt); /* ignore errors */
|
|
tt.c_cflag |= CLOCAL;
|
|
if (flag != CLOCAL)
|
|
/* if not just set CLOCAL then do full default setup */
|
|
{
|
|
tt.c_iflag = BRKINT|ISTRIP|ICRNL|IXON|IXANY;
|
|
tt.c_oflag = OPOST|ONLCR|TAB3;
|
|
if (flag != ECHO)
|
|
tt.c_lflag = ISIG|ICANON;
|
|
else
|
|
tt.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
|
|
tt.c_cc[VINTR] = CINTR;
|
|
tt.c_cc[VQUIT] = CQUIT;
|
|
tt.c_cc[VERASE] = CERASE;
|
|
tt.c_cc[VKILL] = CKILL;
|
|
tt.c_cc[VEOF] = CEOF;
|
|
tt.c_cc[VEOL] = CNUL;
|
|
tt.c_cc[VEOL2] = CNUL;
|
|
}
|
|
tcsetattr(fd, TCSANOW, &tt); /* ignore errors */
|
|
return(0);
|
|
}
|
|
|
|
|
|
WriteTO(int fd, char *buf, int len) /* Loop until all written */
|
|
{ /* Need this for writes to tty opened with O_NDELAY */
|
|
int rc; /* Times out if write does not complete */
|
|
int timeout=40;
|
|
int olen = len;
|
|
|
|
while (timeout && len) {
|
|
rc = write(fd, buf, len);
|
|
if ((rc == -1) && (errno != EAGAIN))
|
|
return rc;
|
|
len -= rc;
|
|
if (len) {
|
|
usleep(100000); /* delay 1/10 second */
|
|
buf += rc;
|
|
timeout--; /* timeout */
|
|
}
|
|
}
|
|
return(olen - len);
|
|
}
|
|
|
|
|
|
#ifdef _DEBUG
|
|
/**************************************************************************
|
|
Dump terminal structures for debugging
|
|
**************************************************************************/
|
|
|
|
dstruct(tp)
|
|
struct terminals *tp;
|
|
{
|
|
struct terminals *thisterm;
|
|
|
|
thisterm = topterm;
|
|
while(thisterm != NULL)
|
|
{
|
|
printf("fd = %d ",thisterm->fd);
|
|
printf("ddev = %s ",thisterm->dispdev);
|
|
printf("Next = %X ",thisterm->next);
|
|
printf("Last = %X \n",thisterm->last);
|
|
thisterm = thisterm->next;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|