Files
seta75D 2e8a93c394 Init
2021-10-11 18:20:23 -03:00

418 lines
12 KiB
C

static char sccsid[] = "@(#)online_util.c 1.1 7/30/92 Copyright Sun Mircosystems Inc.";
/*************************************************************************
This file contains the following routines:
sun_arch() - get the cpu architecture.
sun_unix() - get the unix version level.
sun_cpu() - get the cpu type.
check_superuser() - check the superuser mode.
format_line() - format one long string to make indents of
specified space for lines other than the first
line.
errmsg() - get system error message string.
get_test_id() - get a test id number from known name list.
get_version_id() - get an integer version number from provided string.
get_sccs_version() - get an integer number from SCCS version string.
get_processors_mask() - get processor affinity mask.
get_number_processors() - get a number of processors.
*****************************************************************************/
#include <stdio.h>
#include <ctype.h>
#ifdef SVR4
#include <sys/cpu.h>
#include <sys/uadmin.h>
#include <sys/cpuvar.h>
#else SVR4
#include <mon/idprom.h>
#endif SVR4
#include <sys/ioctl.h>
#include "libonline.h"
extern unsigned gethostid();
int test_id = 999; /* test_id default as 999 */
int version_id = 99;
int subtest_id = 999;
int error_code = 999; /* default value for error exit */
int error_base;
int cpu_num[32]; /* to save the kernel-assigned CPU number */
char *versionid = "unknown_version";
/****************************************************************************
NAME: sun_arch - get cpu architecture.
SYNOPSIS:
int sun_arch()
ARGUMENTS: none
DESCRIPTION:
This routine calls gethostid() to get cpu architecture by looking
at only most significant byte of its output.
RETURN VALUE:
If succeeds, architecture code ARCH3, ARCH3X, ARCH4, ARCH4C, ARCH4M,
or ARCH386 are returned. unknown codes are defaulted to ARCH4C.
MACROS: none
GLOBAL: gethostid()
*****************************************************************************/
int
sun_arch()
{
unsigned hostid;
hostid = gethostid() >> 24;
if (hostid == 0x20) return(ARCH4C); /* for clones */
#ifdef SVR4
switch (hostid & CPU_ARCH) {
case SUN4_ARCH:
return(ARCH4);
case SUN4C_ARCH:
return(ARCH4C);
case SUN4M_ARCH:
return(ARCH4M);
default:
return(ARCH4C); /* so that clone machines will work */
}
#else SVR4
switch (hostid & IDM_ARCH_MASK) {
case IDM_ARCH_SUN4:
return(ARCH4);
case IDM_ARCH_SUN4C:
return(ARCH4C);
case IDM_ARCH_SUN4M:
return(ARCH4M);
default:
return(ARCH4C); /* so that clone machines will work */
}
#endif SVR4
}
/****************************************************************************
NAME: sun_cpu - get the cpu type.
SYNOPSIS:
int sun_cpu()
ARGUMENTS: none
DESCRIPTION:
This routine calls gethostid() to get cpu type by looking
at only most significant byte of its output. It returns
all the possible values of the id_machine field (so far).
RETURN VALUE:
It returns the cpu type hex value according to those defined in
/usr/include/mon/idprom.h.
MACROS: none
GLOBAL: gethostid()
*****************************************************************************/
int
sun_cpu()
{
return (gethostid() >> 24);
}
/****************************************************************************
NAME: sun_unix - get the unix version level.
SYNOPSIS:
char *sun_unix()
DESCRIPTION:
This routine reads /etc/motd file to determin unix version level.
RETURN VALUE:
If succeeds, a string name of the SunOS version level will
return, otherwise 0.
MACROS:
none
GLOBAL: fopen()
*****************************************************************************/
char *
sun_unix()
{
FILE *fp;
static char outstr[20];
char linbuf[256], *outstr_ptr= outstr;
register int i;
if ((fp = fopen ("/etc/motd", "r")) == NULL)
return(NULL);
if (fgets(linbuf, 255, fp) != NULL)
for (i = 14; linbuf[i] != ' '; i++)
*outstr_ptr++ = linbuf[i];
*outstr_ptr = NULL;
return(outstr);
}
/*****************************************************************************
NAME: check_superuser - check the superuser mode.
SYNOPSIS:
check_superuser();
RETURN VALUE: void if in superuser mode; or exit with error message.
GLOBAL: geteuid()
*****************************************************************************/
void
check_superuser()
{
if (geteuid()) {
printf("ERROR: Must be super-user.\n");
exit(1);
}
}
/****************************************************************************
NAME: format_line - format one long string to make indents of specified
space for lines other than the first line.
SYNOPSIS:
void format_line(out_string, in_string, indent)
ARGUMENTS:
input:
char *in_string - input string that needs to be formatted.
int indent - number of space indented for sencond line
and after.
output:
char *out_string - output string after being formatted.
DESCRIPTION:
*****************************************************************************/
void
format_line(out_string, in_string, indent)
char *out_string;
char *in_string;
int indent;
{
int firstline_len = MSG_LINELEN;/* let first line have length of 80 char */
int secline_len;
int first = TRUE; /* always starts from first line */
int i=0, j;
secline_len = firstline_len - indent;
while(*in_string != '\0') {
if(*in_string == '\n') {
i = 0; /* meet a newline, reset char count */
*out_string++ = *in_string++;
continue;
}
i++;
if( !first && (i-firstline_len-1)%secline_len == 0 ) {
*out_string++ = '\n';
for (j=0; j<indent; j++)
*out_string++ = ' ';
while(*in_string == ' ') in_string++;
}
else {
if( first && i%(firstline_len+1) == 0 ){
*out_string++ = '\n';
for (j=0; j<indent; j++)
*out_string++ = ' ';
while(*in_string == ' ') in_string++;
first = FALSE;
}
}
*out_string++ = *in_string++;
}
*out_string = '\0';
}
/****************************************************************************
NAME: errmsg - get system error message string.
SYNOPSIS: char * errmsg(errnum)
ARGUMENTS:
Input: int errnum - system error code
DESCRIPTION:
RETURN VALUE:
returns the string of the system error message, based on the
errnum, to your program, courtesy of Guy Harris.
GLOBAL: sys_nerr, sys_errlist[]
*****************************************************************************/
char * errmsg(errnum)
int errnum;
{
extern int sys_nerr;
extern char *sys_errlist[];
static char errmsgbuf[6+10+1];
static char *errmsg1 = "Error %d";
if (errnum >= 0 && errnum < sys_nerr)
return (sys_errlist[errnum]);
else {
(void) sprintf(errmsgbuf, errmsg1, errnum);
return (errmsgbuf);
}
}
/****************************************************************************
NAME: get_test_id - get a test id number from known name list.
SYNOPSIS: int get_test_id(test_name, name_list)
ARGUMENTS:
Input: char *test_name - testname string to match.
Output: char *name_list[] - a known name list to search.
DESCRIPTION: Used for diagnostics standard message format.
RETURN VALUE: if search successful, return test id number (integer);
otherwise, return 999.
GLOBAL: strcmp()
*****************************************************************************/
int
get_test_id(test_name, name_list)
char *test_name;
char *name_list[];
{
register int i;
for (i=0; name_list[i] != NULL; i++) {
if (!strcmp (name_list[i], test_name))
return (i);
}
return (999); /* Couldn't get test id */
}
/****************************************************************************
NAME: get_version_id - get an integer version number from provided string.
SYNOPSIS: int get_version_id(ptr)
ARGUMENTS:
Input: char *ptr - a string that indicates a version.
DESCRIPTION:
RETURN VALUE: return an integer for the input string:
e.g. return 120 for "1.2" or "1.20" or "1.2+" where '+'
represents any non-digit character.
return 999 if string starts from an non-digit character.
e.g return 999 for "a12" or "+cd
GLOBAL: isdigit(), strlen(), strcat(), atoi().
*****************************************************************************/
int
get_version_id(ptr)
char *ptr;
{
static char buf[20];
char *buf_ptr = buf;
if(!isdigit(*ptr)) return (999);
while (*ptr != '\0') {
if (*ptr != '.')
*buf_ptr++ = isdigit(*ptr)? *ptr: '0';
ptr++;
}
*buf_ptr = '\0';
while(strlen(buf) <3)
strcat(buf, "0");
return (atoi(buf));
}
/****************************************************************************
NAME: get_sccs_version - get an integer number from SCCS version string.
SYNOPSIS: int get_sccs_version(vstring)
ARGUMENTS:
Input: char *vstring - SCCS version string format, e.g. "1.5"
DESCRIPTION:
RETURN VALUE: Return an integer number that only counts the portion right
after '.', e.g. return 5 for "1.5"; return 21 for "2.21".
If no '.' is found in the inpur string, return 99.
GLOBAL : atoi()
*****************************************************************************/
int
get_sccs_version(vstring)
char *vstring;
{
register int count;
count = 0;
while (*vstring++ != '.')
if (++count > 5) return(99);
return (atoi(vstring));
}
/****************************************************************************
NAME: get_processors_mask()
SYNOPSIS:
int get_processors_mask()
ARGUMENTS:
None
DESCRIPTION:
This routine uses the processor affinity masks via ioctl call
to the device driver for the kernel memory devices to find
out the number of processors exist. The normal device to
use is /dev/null. The ioctl call reads the processor affinity
mask value.
MACROS:
none.
RETURN VALUE: unsigned
*****************************************************************************/
int get_processors_mask()
{
unsigned mask_value;
#ifdef SVR4
int i;
unsigned j;
mask_value = 0;
for (i=31; i >= 0; --i)
{
mask_value <<= 1;
j = uadmin(A_STAT_CPU, i, 0);
if (j != -1 && (j&CPU_READY))
++mask_value;
}
return(mask_value);
#else SVR4
int memfd;
memfd = open("/dev/null", 0);
mask_value = 0;
ioctl(memfd, MIOCGPAM, &mask_value);
close(memfd);
if (mask_value == 0) return(1); /* single processor */
else return(mask_value);
#endif SVR4
}
/****************************************************************************
NAME: get_number_processors()
SYNOPSIS:
int get_number_processors()
ARGUMENTS:
input: none.
DESCRIPTION:
This routine get the number of processors. It calls function
get_processors_mask() to read the the processor affinity mask
value. Each bit of the processor affinity mask is set cor-
responding to the existing processor.
MACROS:
none.
RETURN VALUE: int
*****************************************************************************/
int
get_number_processors(mask_value)
int mask_value;
{
int i=0, j=0, bit;
for (bit = 1; bit; bit <<= 1, ++j)
{
if (mask_value & bit)
{
cpu_num[i] = j; /* CPU number starts from 0 */
++i;
}
}
return(i);
}