556 lines
11 KiB
C
556 lines
11 KiB
C
#ifndef lint
|
|
#ifdef SunB1
|
|
static char sccsid[] = "@(#)sys_info.c 1.1 94/10/31 SMI; SunOS MLS";
|
|
#else
|
|
static char sccsid[] = "@(#)sys_info.c 1.1 94/10/31 SMI";
|
|
#endif /* SunB1 */
|
|
#endif lint
|
|
|
|
/*
|
|
* Copyright (c) 1989 Sun Microsystems, Inc.
|
|
*/
|
|
|
|
/*
|
|
* Name: sys_info.c
|
|
*
|
|
* Description: This file contains the routines necessary for
|
|
* interfacing with the 'sys_info' structure file. The
|
|
* layout of a 'sys_info' file is as follows (order is no
|
|
* longer important):
|
|
*
|
|
* hostname= (comma-separated list of hostnames)
|
|
* ether_name= (comma-separated list of ethernet
|
|
* interface names)
|
|
* ip= (comma-separated list of internet
|
|
* addresses)
|
|
* hostname0= (only for backward compatibility)
|
|
* ( replaced by hostname= above )
|
|
* hostname1= ( " )
|
|
* sys_type=
|
|
* ether_name0= ( " )
|
|
* ether_name1= ( " )
|
|
* ip0= ( " )
|
|
* ip0_minlab= (SunB1)
|
|
* ip0_maxlab= (SunB1)
|
|
* ip1= ( " )
|
|
* ip1_minlab= (SunB1)
|
|
* ip1_maxlab= (SunB1)
|
|
* yp_type=
|
|
* domainname=
|
|
* op_type=
|
|
* reboot=
|
|
* rewind=
|
|
* arch_str=
|
|
* root=
|
|
* user=
|
|
* termtype=
|
|
* timezone=
|
|
* server=
|
|
* server_ip=
|
|
* exec_path=
|
|
* kvm_path=
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "install.h"
|
|
#include "menu.h"
|
|
|
|
|
|
/*
|
|
* Local functions:
|
|
*/
|
|
static char * out_std();
|
|
static char * cv_op_to_str();
|
|
static int cv_str_to_op();
|
|
static int cv_str_to_sys();
|
|
static char * cv_sys_to_str();
|
|
static int inp_hostname();
|
|
static int inp_ethername();
|
|
static int inp_ip();
|
|
static char *out_hostname();
|
|
static char *out_ethername();
|
|
static char *out_ip();
|
|
static struct key_xlat_t *lookup();
|
|
|
|
|
|
|
|
|
|
/*
|
|
* Local variables:
|
|
*/
|
|
static sys_info sys; /* local copy of sys_info */
|
|
|
|
|
|
/*
|
|
* Key translation table:
|
|
*/
|
|
|
|
/*
|
|
* The meaning of this table has been modified slightly because of the
|
|
* structure change of sys_info required by multiple ethernet requirements.
|
|
* The first field is the keyword name appearing to the left of the equal
|
|
* sign in the sys_info file. The next field is the input handling routine,
|
|
* called when reading the sys_info file -- if this is 0, data is copied as
|
|
* characters to the data_p field (the last field). The third field is the
|
|
* output handling routine which returns a string to be inserted after the
|
|
* "=" in the output sys_info file. If this field is zero, nothing is
|
|
* written (indicates backward compatibility keywords -- can be read, but
|
|
* the save routine does not write it out.
|
|
*/
|
|
|
|
static key_xlat key_list[] = {
|
|
{ "hostname", inp_hostname, out_hostname, (char*) sys.ethers },
|
|
{ "sys_type", cv_str_to_sys, cv_sys_to_str, (char *)&sys.sys_type},
|
|
{ "ether_name", inp_ethername, out_ethername, (char *) sys.ethers },
|
|
{ "ip", inp_ip, out_ip, (char *) sys.ethers },
|
|
{ "hostname0", 0, 0, sys.hostname0 },
|
|
{ "hostname1", 0, 0, sys.hostname1 },
|
|
{ "ether_name0", 0, 0, sys.ether_name0 },
|
|
{ "ether_name1", 0, 0, sys.ether_name1 },
|
|
{ "ip0", 0, 0, sys.ip0 },
|
|
{ "ip1", 0, 0, sys.ip1 },
|
|
|
|
#ifdef SunB1
|
|
{ "ip0_minlab", cv_str_to_lab, cv_lab_to_str,(char *)&sys.ip0_minlab },
|
|
{ "ip0_maxlab", cv_str_to_lab, cv_lab_to_str,(char *)&sys.ip0_maxlab },
|
|
{ "ip1_minlab", cv_str_to_lab, cv_lab_to_str,(char *)&sys.ip1_minlab },
|
|
{ "ip1_maxlab", cv_str_to_lab, cv_lab_to_str,(char *)&sys.ip1_maxlab },
|
|
#endif /* SunB1 */
|
|
|
|
{ "yp_type", cv_str_to_yp, cv_yp_to_str, (char *)&sys.yp_type },
|
|
{ "domainname", 0, out_std, sys.domainname },
|
|
{ "op_type", cv_str_to_op, cv_op_to_str, (char *)&sys.op_type },
|
|
{ "reboot", cv_str_to_ans, cv_ans_to_str, (char *) &sys.reboot },
|
|
{ "rewind", cv_str_to_ans, cv_ans_to_str, (char *) &sys.rewind },
|
|
{ "arch_str", 0, out_std, sys.arch_str },
|
|
{ "root", 0, out_std, sys.root },
|
|
{ "user", 0, out_std, sys.user },
|
|
{ "termtype", 0, out_std, sys.termtype },
|
|
{ "timezone", 0, out_std, sys.timezone },
|
|
{ "server", 0, out_std, sys.server },
|
|
{ "server_ip", 0, out_std, sys.server_ip },
|
|
{ "exec_path", 0, out_std, sys.exec_path },
|
|
{ "kvm_path", 0, out_std, sys.kvm_path },
|
|
{ "static_sizing", cv_str_to_ans, cv_ans_to_str, (char *) &sys.static_sizing},
|
|
|
|
{ NULL }
|
|
};
|
|
|
|
static struct key_xlat_t *
|
|
lookup(p)
|
|
char *p;
|
|
{
|
|
struct key_xlat_t *sysx;
|
|
|
|
for (sysx = key_list; sysx->key_name != 0; sysx++)
|
|
if (strcmp(sysx->key_name, p) == 0)
|
|
return sysx;
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
* Name: read_sys_info()
|
|
*
|
|
* Description: Read system information from 'name' into 'sys_p'.
|
|
* Returns 1 if the file was saved successfully, and -1 if
|
|
* there was an error.
|
|
*/
|
|
|
|
int
|
|
read_sys_info(name, sys_p)
|
|
char * name;
|
|
sys_info * sys_p;
|
|
{
|
|
char buf[BUFSIZ]; /* buffer for I/O */
|
|
FILE * fp; /* file pointer for name */
|
|
struct key_xlat_t *sysx;
|
|
|
|
|
|
/*
|
|
* Always zero out the information buffer.
|
|
*/
|
|
bzero((char *) sys_p, sizeof(*sys_p));
|
|
|
|
fp = fopen(name, "r");
|
|
if (fp == NULL)
|
|
return(0);
|
|
|
|
bzero((char *) &sys, sizeof(sys));
|
|
bzero(buf, sizeof(buf));
|
|
|
|
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
|
char *cp;
|
|
char *cp1;
|
|
|
|
if ((cp = strchr(buf, '=')) == 0)
|
|
continue;
|
|
*cp++ = 0;
|
|
if ((cp1 = strchr(cp,'\n')) != 0) {
|
|
*cp1 = 0;
|
|
}
|
|
if ((sysx = lookup(buf)) != 0) {
|
|
if (sysx->key_func == 0) {
|
|
(void) strcpy(sysx->data_p, cp);
|
|
} else {
|
|
(*sysx->key_func)(cp, sysx->data_p);
|
|
}
|
|
}
|
|
}
|
|
|
|
*sys_p = sys; /* copy valid sys_info */
|
|
|
|
(void) fclose(fp);
|
|
|
|
return(1);
|
|
} /* end read_sys_info() */
|
|
|
|
|
|
|
|
|
|
/*
|
|
* Name: save_sys_info()
|
|
*
|
|
* Description: Save system information pointed to by 'sys_p'
|
|
* into 'name'.
|
|
*
|
|
* Returns 1 if the file was saved successfully, and -1 if
|
|
* there was an error.
|
|
*/
|
|
|
|
int
|
|
save_sys_info(name, sys_p)
|
|
char * name;
|
|
sys_info * sys_p;
|
|
{
|
|
FILE * fp; /* file pointer for name */
|
|
struct key_xlat_t *sysx;
|
|
|
|
|
|
sys = *sys_p; /* copy valid sys_info */
|
|
|
|
fp = fopen(name, "w");
|
|
if (fp == NULL) {
|
|
menu_log("%s: %s: cannot open file for writing.", progname,
|
|
name);
|
|
return(-1);
|
|
}
|
|
|
|
for (sysx = key_list; sysx->key_name != 0; sysx++) {
|
|
if (sysx->code_func != 0) {
|
|
(void) fprintf(fp, "%s=%s\n", sysx->key_name, (sysx->code_func)(sysx->data_p));
|
|
}
|
|
}
|
|
|
|
(void) fclose(fp);
|
|
|
|
return(1);
|
|
} /* end save_sys_info() */
|
|
|
|
static char*
|
|
out_std(p)
|
|
char *p;
|
|
{
|
|
return p;
|
|
}
|
|
|
|
static int
|
|
inp_hostname(name, e)
|
|
char *name;
|
|
struct ether_interface *e;
|
|
{
|
|
int i = 0;
|
|
|
|
while (name != 0 && i < MAX_ETHER_INTERFACES) {
|
|
char *p = strchr(name,',');
|
|
char *newname = 0;
|
|
|
|
if (p != 0) {
|
|
*p = 0;
|
|
newname = p+1;
|
|
}
|
|
(void) strcpy(e->hostname,name);
|
|
name = newname;
|
|
i++;
|
|
e++;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
inp_ethername(name, e)
|
|
char *name;
|
|
struct ether_interface *e;
|
|
{
|
|
int i = 0;
|
|
|
|
while (name != 0 && i < MAX_ETHER_INTERFACES) {
|
|
char *p = strchr(name,',');
|
|
char *newname = 0;
|
|
|
|
if (p != 0) {
|
|
*p = 0;
|
|
newname = p+1;
|
|
}
|
|
(void) strcpy(e->interface_name,name);
|
|
name = newname;
|
|
i++;
|
|
e++;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
inp_ip(name, e)
|
|
char *name;
|
|
struct ether_interface *e;
|
|
{
|
|
int i = 0;
|
|
|
|
while (name != 0 && i < MAX_ETHER_INTERFACES) {
|
|
char *p = strchr(name,',');
|
|
char *newname = 0;
|
|
|
|
if (p != 0) {
|
|
*p = 0;
|
|
newname = p+1;
|
|
}
|
|
(void) strcpy(e->internet_addr,name);
|
|
name = newname;
|
|
i++;
|
|
e++;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static char buff[BUFSIZ];
|
|
|
|
static char *
|
|
out_hostname(e)
|
|
struct ether_interface *e;
|
|
{
|
|
char *cp = buff;
|
|
int nbr_nulls = 0;
|
|
int i;
|
|
|
|
*cp = 0;
|
|
for (i = 0; i < MAX_ETHER_INTERFACES; i++, e++) {
|
|
if (*e->hostname != 0) {
|
|
while (nbr_nulls > 0) {
|
|
*cp++ = ',';
|
|
nbr_nulls--;
|
|
}
|
|
(void) strcpy(cp, e->hostname);
|
|
cp += strlen(cp);
|
|
}
|
|
nbr_nulls++;
|
|
}
|
|
return buff;
|
|
}
|
|
|
|
static char *
|
|
out_ethername(e)
|
|
struct ether_interface *e;
|
|
{
|
|
char *cp = buff;
|
|
int nbr_nulls = 0;
|
|
int i;
|
|
|
|
*cp = 0;
|
|
for (i = 0; i < MAX_ETHER_INTERFACES; i++, e++) {
|
|
if (*e->interface_name != 0) {
|
|
while (nbr_nulls > 0) {
|
|
*cp++ = ',';
|
|
nbr_nulls--;
|
|
}
|
|
(void) strcpy(cp, e->interface_name);
|
|
cp += strlen(cp);
|
|
}
|
|
nbr_nulls++;
|
|
}
|
|
return buff;
|
|
}
|
|
|
|
static char *
|
|
out_ip(e)
|
|
struct ether_interface *e;
|
|
{
|
|
char *cp = buff;
|
|
int nbr_nulls = 0;
|
|
int i;
|
|
|
|
*cp = 0;
|
|
for (i = 0; i < MAX_ETHER_INTERFACES; i++, e++) {
|
|
if (*e->internet_addr != 0) {
|
|
while (nbr_nulls > 0) {
|
|
*cp++ = ',';
|
|
nbr_nulls--;
|
|
}
|
|
(void) strcpy(cp, e->internet_addr);
|
|
cp += strlen(cp);
|
|
}
|
|
nbr_nulls++;
|
|
}
|
|
return buff;
|
|
}
|
|
|
|
static conv op_list[] = {
|
|
"install", OP_INSTALL,
|
|
"upgrade", OP_UPGRADE,
|
|
|
|
(char *) 0, 0
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
* Name: cv_op_to_str()
|
|
*
|
|
* Description: Convert an operation code into a string. If the
|
|
* operation code cannot be converted, then NULL is returned.
|
|
*/
|
|
|
|
static char *
|
|
cv_op_to_str(op_p)
|
|
int * op_p;
|
|
{
|
|
conv * cv; /* conversion pointer */
|
|
|
|
|
|
for (cv = op_list; cv->conv_text; cv++)
|
|
if (cv->conv_value == *op_p)
|
|
return(cv->conv_text);
|
|
return("");
|
|
} /* end cv_op_to_str() */
|
|
|
|
|
|
|
|
|
|
/*
|
|
* Name: cv_str_to_op()
|
|
*
|
|
* Description: Convert a string into an operation code. If the
|
|
* string cannot be converted, then 0 is returned.
|
|
*/
|
|
|
|
static int
|
|
cv_str_to_op(str, data_p)
|
|
char * str;
|
|
int * data_p;
|
|
{
|
|
conv * cv; /* conversion pointer */
|
|
|
|
|
|
for (cv = op_list; cv->conv_text; cv++)
|
|
if (strcmp(cv->conv_text, str) == 0) {
|
|
*data_p = cv->conv_value;
|
|
return(1);
|
|
}
|
|
|
|
*data_p = 0;
|
|
return(0);
|
|
} /* end cv_str_to_op() */
|
|
|
|
|
|
|
|
|
|
static conv sys_list[] = {
|
|
"standalone", SYS_STANDALONE,
|
|
"server", SYS_SERVER,
|
|
"dataless", SYS_DATALESS,
|
|
|
|
(char *) 0, 0
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
* Name: cv_sys_to_str()
|
|
*
|
|
* Description: Convert a system type into a string. If the system
|
|
* type cannot be converted, then NULL is returned.
|
|
*/
|
|
|
|
static char *
|
|
cv_sys_to_str(sys_p)
|
|
int * sys_p;
|
|
{
|
|
conv * cv; /* conversion pointer */
|
|
|
|
|
|
for (cv = sys_list; cv->conv_text; cv++)
|
|
if (cv->conv_value == *sys_p)
|
|
return(cv->conv_text);
|
|
return("");
|
|
} /* end cv_sys_to_str() */
|
|
|
|
|
|
|
|
|
|
/*
|
|
* Name: cv_str_to_sys()
|
|
*
|
|
* Description: Convert a string into a system type. If the string
|
|
* cannot be converted, then 0 is returned.
|
|
*/
|
|
|
|
static int
|
|
cv_str_to_sys(str, data_p)
|
|
char * str;
|
|
int * data_p;
|
|
{
|
|
conv * cv; /* conversion pointer */
|
|
|
|
|
|
for (cv = sys_list; cv->conv_text; cv++)
|
|
if (strcmp(cv->conv_text, str) == 0) {
|
|
*data_p = cv->conv_value;
|
|
return(1);
|
|
}
|
|
|
|
*data_p = 0;
|
|
return(0);
|
|
} /* end cv_str_to_sys() */
|
|
|
|
|
|
/*
|
|
* Name: read_sys_release()
|
|
*
|
|
* Description: Read the system RELEASE file and put it into buffer.
|
|
*
|
|
* Return Value: 0 : if the reads went ok
|
|
* -1: if the reads failed
|
|
*/
|
|
int
|
|
read_sys_release(buffer)
|
|
char * buffer; /* buffer to store realease in */
|
|
{
|
|
FILE * fp; /* scratch file pointer */
|
|
|
|
if ((fp = fopen(RELEASE, "r")) == (FILE *)NULL) {
|
|
menu_mesg("%s: failed to open %s", progname, RELEASE);
|
|
return(-1);
|
|
}
|
|
|
|
if (fgets(buffer, MEDIUM_STR, fp ) == (char *)NULL) {
|
|
menu_mesg("%s: failed to read release from %s", progname,
|
|
RELEASE);
|
|
(void) fclose(fp);
|
|
return(-1);
|
|
}
|
|
|
|
/*
|
|
* Strip the newline off the end of the string
|
|
*/
|
|
buffer[strlen(buffer) - 1] = '\0';
|
|
|
|
(void) fclose(fp);
|
|
return(0);
|
|
|
|
} /* end read_sys_release() */
|
|
|
|
|