1
0
Files
irix-657m-src/eoe/cmd/sss/availmon/amformat/reportutils.c
2022-09-29 17:59:04 +03:00

501 lines
19 KiB
C

/*---------------------------------------------------------------------------*/
/* */
/* Copyright 1992-1998 Silicon Graphics, Inc. */
/* All Rights Reserved. */
/* */
/* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics Inc.; */
/* contents of this file may not be disclosed to third parties, copied or */
/* duplicated in any form, in whole or in part, without the prior written */
/* permission of Silicon Graphics, Inc. */
/* */
/* RESTRICTED RIGHTS LEGEND: */
/* Use,duplication or disclosure by the Government is subject to restrictions*/
/* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data */
/* and Computer Software clause at DFARS 252.227-7013, and/or in similar or */
/* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished - */
/* rights reserved under the Copyright Laws of the United States. */
/* */
/*---------------------------------------------------------------------------*/
#ident "$Revision: 1.3 $"
/*---------------------------------------------------------------------------*/
/* reportutils.c */
/* */
/* various utilities used to print AVAILABILITY, DIAGNOSTIC & PAGER */
/* reports */
/* */
/* Todo : */
/* - Include NOTMULTIUSER in START & PREVSTART */
/* - Change check[Hinv|Versions|Gfx]Change to read from SSDB for */
/* actual changes (integration with ConfigMon) */
/*---------------------------------------------------------------------------*/
#include <amstructs.h>
#include <amformat.h>
#include <amfields.h>
#include <amevent.h>
#include <amdefs.h>
#include <time.h>
#include <sys/times.h>
#include <libgen.h>
/*---------------------------------------------------------------------------*/
/* Function Prototypes */
/*---------------------------------------------------------------------------*/
void getRegistrationData(Event_t *, int);
__uint32_t getReportOpts(__uint32_t);
int PrintReport(Event_t *, repparams_t *, __uint32_t, int);
int checkHinvChange(Event_t *);
int checkGfxChange(Event_t *);
int checkVersionsChange(Event_t *);
/*---------------------------------------------------------------------------*/
/* Macros */
/*---------------------------------------------------------------------------*/
#define PrintFieldName(x,y) ( fprintf(x, "%s%s", \
repFields[y].field_name, SEPERATOR))
/*---------------------------------------------------------------------------*/
/* Name : getRegistrationData */
/* Purpose : Generates required data for a Registration Event */
/* Inputs : Event Structure and a flag */
/* Outputs : None */
/*---------------------------------------------------------------------------*/
void getRegistrationData(Event_t *event, int flag)
{
FILE *fp;
char buffer[20] = "0";
if (event == NULL ) return;
if ( flag ) {
event->eventcode = REGISTER;
event->hinvchange = 1;
event->verchange = 1;
} else {
event->eventcode = DE_REGISTER;
event->hinvchange = 0;
event->verchange = 0;
}
event->eventtime = time(0);
/*-----------------------------------------------------------------------*/
/* Open PREVSTARTFILE and get the value of prevstart */
/*-----------------------------------------------------------------------*/
if ( (fp = fopen(PREVSTARTFILE, "r")) != NULL ) {
fread(buffer, 1, 20, fp);
event->prevstart = atoi(buffer);
fclose(fp);
}
if ( (fp = fopen(LASTTICKFILE, "r")) != NULL ) {
fread(buffer, 1, 20, fp);
event->lasttick = atoi(buffer);
fclose(fp);
}
return;
}
/*---------------------------------------------------------------------------*/
/* Name : getReportOpts */
/* Purpose : Determines which type of report to generate */
/* Inputs : Eventcode */
/* Outputs : Type of Report */
/*---------------------------------------------------------------------------*/
__uint32_t getReportOpts(__uint32_t EventCode)
{
if ( !isvalid(EventCode) ) {
return(NOTANEVENT);
} else if (iscontrolled(EventCode)) {
return(REBOOTREP);
} else if (isderegis(EventCode)) {
return(DEREGISREP);
} else if (isregis(EventCode)) {
return(REGISREP);
} else if (isidcorr(EventCode)) {
return(IDCORRREP);
} else if (isstatusupd(EventCode)) {
return(STATUSREP);
} else if (isunscheduled(EventCode)) {
return(UNSCHEDREP);
} else if (isliveerrrep(EventCode)) {
return(LIVEERRREP);
} else if (islivesysrep(EventCode)) {
return(LIVESYSREP);
} else {
return(NOTANEVENT);
}
}
/*---------------------------------------------------------------------------*/
/* Name : PrintReport */
/* Purpose : Main utility to generate Availmon Report */
/* Inputs : Event Structure, report types, Configuration flag and resendflag*/
/* Outputs : -1 or 0 */
/*---------------------------------------------------------------------------*/
int PrintReport(Event_t *event, repparams_t *nParam, __uint32_t ConfFlag,
int resendflag)
{
FILE *outFile = NULL;
__uint32_t ReportOpts = 0;
char tmpBuffer[MAXVARCHARSIZE];
char tmpBuffer1[MAXVARCHARSIZE];
int noBytes = 0;
int iFlag = 0; /* Flag for interesting Report */
if ( event == NULL ) return(-1);
if ( nParam == NULL ) return (-1);
else if ( nParam->filename == NULL ) {
outFile = stdout;
} else {
if ( (outFile = fopen(nParam->filename, "w")) == NULL ) {
return(-1);
}
}
if ( nParam->reportType == PAGER ) {
fprintf(outFile, "%s%s\n",
((event->hostname != NULL) ? event->hostname : "unknown"),
SEPERATOR);
fprintf(outFile, "%s\n",
(char *) getEventDescription(event->eventcode));
if ( event->bounds >= 0 ) {
fprintf(outFile, "%s%s\n", repFields[SUMMARYVAL].field_name,
SEPERATOR);
if ( event->summary && !(event->flag & SUMMARYISFILE) ) {
fprintf(outFile, "%s\n",
strccpy(tmpBuffer,event->summary));
} else {
fprintf(outFile, "unknown\n");
}
}
} else {
if ( (ReportOpts = getReportOpts(event->eventcode)) == 0 )
return(-1);
/*-------------------------------------------------------------------*/
/* First, print out the header of Availmon report which contains */
/* SERIALNUM, HOSTNAME, AMRVERSION and UNAME. In case a report is */
/* being resent, we print out RESEND also. */
/*-------------------------------------------------------------------*/
if ( ReportOpts & repFields[SERIALNUMVAL].flag ) {
PrintFieldName(outFile, SERIALNUMVAL);
fprintf(outFile, "%s\n",
((event->serialnum != NULL) ? event->serialnum:"unknown"));
}
if ( ReportOpts & repFields[HOSTNAMEVAL].flag ) {
PrintFieldName(outFile, HOSTNAMEVAL);
fprintf(outFile, "%s\n",
((event->hostname != NULL) ? event->hostname:"unknown"));
}
if ( ReportOpts & repFields[AMRVERSIONVAL].flag ) {
fprintf(outFile, "%s%s%s\n",
repFields[AMRVERSIONVAL].field_name,
SEPERATOR, AMRVERSIONNUM);
}
if ( resendflag ) {
fprintf(outFile, "RESEND|\n");
}
if ( ReportOpts & repFields[UNAMEVAL].flag ) {
PrintFieldName(outFile, UNAMEVAL);
if (checkCmd(UNAME))
appendOutput(outFile, UNAMECOMMAND, ISCOMMAND,NULL);
}
/*-------------------------------------------------------------------*/
/* After the header of the report is printed out, we need to output */
/* the eventtime and prevstart. A note on prevstart : If the mach */
/* ne is brought up from a single user mode, then prevstart needs to */
/* identify the previous event as not a multi user event. We deter */
/* mine this by looking at the value of event->flag. If this flag */
/* (which is set by /etc/init.d/availmon) says that the previous even*/
/* t is Single User, then we include NOTMULTIUSER in the line that is*/
/* printed out. */
/*-------------------------------------------------------------------*/
if ( ReportOpts & repFields[PREVSTARTVAL].flag ) {
PrintFieldName(outFile, PREVSTARTVAL);
fprintf(outFile, "%ld%s%.24s",
((event->prevstart > 0) ? event->prevstart : -1),
SEPERATOR,
((event->prevstart>0)?ctime(&event->prevstart):"unknown"));
if ( event->flag & PREVEVENTISSU )
fprintf(outFile, "|NOTMULTIUSER");
fprintf(outFile, "\n");
}
if ( ReportOpts & repFields[EVENTVAL].flag ) {
PrintFieldName(outFile, EVENTVAL);
fprintf(outFile, "%d%s", TOOLD(event->eventcode),SEPERATOR);
fprintf(outFile, "%ld%s%s",
((event->eventtime > 0) ? event->eventtime : -1),
SEPERATOR,
((event->eventtime>0)?ctime(&event->eventtime):"unknown\n"));
}
if ( ReportOpts & repFields[OLDSERIALNUMVAL].flag) {
if ( event->flag & DIAGTYPE_OSERL ) {
PrintFieldName(outFile, OLDSERIALNUMVAL);
fprintf(outFile, "%s\n",
((event->diagtype != NULL) ? event->diagtype : "unknown"));
noBytes = snprintf(&tmpBuffer1[noBytes],
MAXVARCHARSIZE,
"%s%s%s",
repFields[OLDSERIALNUMVAL].field_name,
SEPERATOR,
((event->diagtype != NULL) ? event->diagtype : "unknown"));
event->summary = tmpBuffer1;
}
}
if ( ReportOpts & repFields[OLDHOSTNAMEVAL].flag) {
if ( event->flag & DIAGFILE_OHOST ) {
PrintFieldName(outFile, OLDHOSTNAMEVAL);
fprintf(outFile, "%s\n",
((event->diagfile != NULL) ? event->diagfile : "unknown"));
if ( noBytes > 0 ) {
noBytes += snprintf(&tmpBuffer1[noBytes],
MAXVARCHARSIZE, "\n");
}
noBytes = snprintf(&tmpBuffer1[noBytes],
MAXVARCHARSIZE,
"%s%s%s",
repFields[OLDHOSTNAMEVAL].field_name,
SEPERATOR,
((event->diagfile != NULL) ? event->diagfile : "unknown"));
event->summary = tmpBuffer1;
}
}
if ( ReportOpts & repFields[LASTTICKVAL].flag ) {
PrintFieldName(outFile, LASTTICKVAL);
fprintf(outFile, "%ld%s%s",
((event->lasttick > 0) ? event->lasttick : -1),
SEPERATOR,
((event->lasttick>0)?ctime(&event->lasttick):"unknown\n"));
}
if ( ReportOpts & repFields[STATUSINTERVALVAL].flag ) {
PrintFieldName(outFile, STATUSINTERVALVAL);
fprintf(outFile, "%d\n",
((event->statusinterval > 0) ? event->statusinterval:0));
}
/*-------------------------------------------------------------------*/
/* We need to include NOTMULTIUSER in start field if the event is */
/* a single user event. See comments for PREVSTART above. */
/*-------------------------------------------------------------------*/
if ( ReportOpts & repFields[STARTVAL].flag ) {
PrintFieldName(outFile, STARTVAL);
fprintf(outFile, "%ld%s%.24s",
((event->starttime > 0) ? event->starttime : -1),
SEPERATOR,
((event->starttime>0)?ctime(&event->starttime):"unknown"));
if ( event->flag & EVENTISSU )
fprintf(outFile, "|NOTMULTIUSER");
fprintf(outFile, "\n");
}
if ( ReportOpts & repFields[SUMMARYVAL].flag ) {
if ( event->summary ) {
if ( event->flag & SUMMARYISFILE ) {
appendOutput(outFile, event->summary, !ISCOMMAND, "SUMMARY");
} else {
fprintf(outFile, "SUMMARY|Begin\n%s\nSUMMARY|End\n",
strccpy(tmpBuffer,event->summary));
}
}
}
if ( ReportOpts & repFields[DEREGISTRATIONVAL].flag ) {
fprintf(outFile, "%s%s\n",
repFields[DEREGISTRATIONVAL].field_name,
SEPERATOR);
}
if ( ReportOpts & repFields[REGISTRATIONVAL].flag ) {
fprintf(outFile, "%s%s\n",
repFields[REGISTRATIONVAL].field_name,
SEPERATOR);
}
/*-------------------------------------------------------------------*/
/* Now, we have printed out all the fields that are common to an */
/* availability and diagnostic reports. We need to do some more work*/
/* if the report is a diagnostic report. */
/*-------------------------------------------------------------------*/
if ( nParam->reportType == DIAGNOSTIC && !isidcorr(event->eventcode)){
if ( event->diagtype != NULL ) {
if ( event->diagfile != NULL ) {
appendOutput(outFile, event->diagfile, !ISCOMMAND,
event->diagtype);
iFlag++;
} else {
fprintf(outFile, "%s%sBegin\nunknown\n%s%sEnd\n",
event->diagtype, SEPERATOR, event->diagtype,
SEPERATOR);
}
}
if ( ReportOpts & repFields[SYSLOGVAL].flag ) {
if ( event->syslog && !resendflag ) {
appendOutput(outFile, event->syslog, !ISCOMMAND,
repFields[SYSLOGVAL].field_name);
iFlag++;
} else if ( resendflag ) {
if ( event->bounds >= 0 && event->syslog ) {
appendOutput(outFile, event->syslog, !ISCOMMAND,
repFields[SYSLOGVAL].field_name);
} else {
fprintf(outFile, "%s%sBegin\n",
repFields[SYSLOGVAL].field_name, SEPERATOR);
fprintf(outFile,"Can't recreate SYSLOG information\n");
fprintf(outFile, "%s%sEnd\n",
repFields[SYSLOGVAL].field_name, SEPERATOR);
}
} else {
fprintf(outFile, "%s%sBegin\nunknown\n%s%sEnd\n",
repFields[SYSLOGVAL].field_name,SEPERATOR,
repFields[SYSLOGVAL].field_name,SEPERATOR);
}
}
/*---------------------------------------------------------------*/
/* The diagnostic report normally contains VERSIONS, HINV and */
/* GFXINFO information. This information is sent in a report on */
/* a change being identified. HINV and GFXINFO are sent only if */
/* 'hinvupdate' flag is turned on. VERSIONS is sent whenever a */
/* change in versions info. is identified. The startup script */
/* of Availmon identifies whether a change occured in HINV or */
/* VERSIONS and sends us the flag to update or not */
/*---------------------------------------------------------------*/
if ( (ReportOpts & repFields[VERSIONSVAL].flag) && !resendflag ) {
if ( checkVersionsChange(event) && checkCmd(VERSIONS) ) {
appendOutput(outFile, VERSIONSCOMMAND, ISCOMMAND,
"VERSIONS");
iFlag++;
}
}
if ( (ReportOpts & repFields[HINVVAL].flag) && !resendflag ) {
if ( (ConfFlag & HINVUPDATE) && checkHinvChange(event) && checkCmd(HINV) ) {
appendOutput(outFile, HINVCOMMAND, ISCOMMAND,
"HINV");
iFlag++;
}
}
if ( (ReportOpts & repFields[GFXINFOVAL].flag) && !resendflag ) {
if ( (ConfFlag & HINVUPDATE) && checkGfxChange(event) && checkCmd(GFX) ) {
appendOutput(outFile, GFXCOMMAND, ISCOMMAND,
"GFXINFO");
iFlag++;
}
}
/*---------------------------------------------------------------*/
/* Since availmon reports are identified based on the subject by */
/* amreceive, we need to put proper subject in the report */
/*---------------------------------------------------------------*/
if ( iFlag ) {
nParam->subject[0] = 'I';
} else {
nParam->subject[0] = 'D';
}
} else if (nParam->reportType==DIAGNOSTIC &&isidcorr(event->eventcode)){
nParam->subject[0] = 'I';
} else {
nParam->subject[0] = 'A';
}
/*-------------------------------------------------------------------*/
/* In case of a REGISTRATION/DEREGISTRATION/IDCORRECTION reports, the*/
/* subject should contain -R so that amreceive can identify it */
/*-------------------------------------------------------------------*/
if ( isidcorr(event->eventcode) || isregis(event->eventcode)
|| isderegis(event->eventcode) ) {
nParam->subject[1] = '-';
nParam->subject[2] = 'R';
}
}
if ( outFile ) fclose(outFile);
return(iFlag);
}
/*---------------------------------------------------------------------------*/
/* Name : checkHinvChange */
/* Purpose : Checks whether HINV data needs to be incorporated in the report */
/* Inputs : None */
/* Outputs : 1 or 0 */
/*---------------------------------------------------------------------------*/
int checkHinvChange(Event_t *e)
{
if ( e->hinvchange > 0 ) return(1);
return(0);
}
/*---------------------------------------------------------------------------*/
/* Name : checkGfxChange */
/* Purpose : Checks whether GFXINFO data needs to go in a report or not */
/* Inputs : None */
/* Outputs : 1 or 0 */
/*---------------------------------------------------------------------------*/
int checkGfxChange (Event_t *e)
{
if ( e->hinvchange > 0 ) return(1);
return(0);
}
/*---------------------------------------------------------------------------*/
/* Name : checkVersionsChange */
/* Purpose : Checks whether VERSIONS data needs to go in a report or not */
/* Inputs : None */
/* Outputs : 1 or 0 */
/*---------------------------------------------------------------------------*/
int checkVersionsChange(Event_t *e)
{
if ( e->verchange > 0 ) return(1);
return(0);
}