saga.c revision d2117003c7d0588abeea5ed1b925b77f025e2c96
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#pragma ident "%Z%%M% %I% %E% SMI"
#include "saghdr.h"
#include <limits.h>
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
char cmd[300];
long sardoff;
static void parse(struct p *p);
static void plot(struct p[], int, char *, char *, char *, char *);
static void scale(struct p[], int, char *, char *, char *, char *);
int
{
extern char cmd[];
char sarg[10];
char earg[10];
char iarg[10];
char yarg[200];
char xarg[100];
char Targ[10];
char title[60];
int n, i;
struct p p[6];
char sardfile[20];
int c;
char temp[80];
char *strcpy();
*Targ = '\0';
#ifndef u370
yarg, "%usr 0 100; %usr + %sys 0 100; %usr + %sys + %wio 0 100");
#else
"%usr 0 100; %usr + %usup 0 100; %usr + %usup + %tss 0 100");
#endif
switch (c) {
case 's':
sizeof (sarg)) {
"-s argument too long: %s\n", optarg);
exit(1);
}
break;
case 'e':
sizeof (earg)) {
"-e argument too long: %s\n", optarg);
exit(1);
}
break;
case 'i':
sizeof (iarg)) {
"-i argument too long: %s\n", optarg);
exit(1);
}
break;
case 'f':
sizeof (farg)) {
"-f argument too long: %s\n", optarg);
exit(1);
}
break;
case 'y':
sizeof (yarg)) {
"-y argument too long: %s\n", optarg);
exit(1);
}
break;
case 'x':
sizeof (xarg)) {
"-x argument too long: %s\n", optarg);
exit(1);
}
break;
case 'T':
sizeof (Targ)) {
"-T argument too long: %s\n", optarg);
exit(1);
}
break;
case '?':
"Usage: sag -s hh:mm -e hh:mm -i "
"sec -f safile -T term\n");
"\t -x \"spec\" -y \"spec[;spec]...\"\n");
"\twhere spec is name[ op name]...[lo hi]\n");
"\tand name is a hdrstr that may include "
"[devstr]\n");
exit(2);
}
/*
* Test xarg, break yarg into ";" separated graph commands
*/
*temp = '\0';
*(p[0].spec) = '\0';
"More than one x-axis spec not allowed:\n%s\n", xarg);
exit(2);
}
*temp = '\0';
*(p[i].spec) = '\0';
nplot++;
i++;
}
if (n < 2)
break;
}
if (DEBUG) {
for (i = 0; i < 6; i++)
}
/*
* Parse each spec
*/
for (i = 0; i <= nplot; i++)
parse(&p[i]);
/*
* Run sar, with output to sardfile.
*/
"-e '/:/h' "
"-e '/:/s/ .*//' "
"-e '/:/x' "
"-e '/^ /G' "
"-e '/^ /s/\\(.*\\)\\n\\(.*\\)/\\2\\1/' "
"-e '/proc-sz/,$s/\\/ */\\//g' "
"-e '/proc-sz/,$s/\\/[^ ]*//g' "
"-e 's/ / /g' "
"-e 's/ */ /g' "
"-e '/^ /s///' "
"-e '/^$/d' "
"> %s",
exit(2);
}
for (i = 0; i < n; i++) {
}
for (i = 0; i <= nplot; i++)
if (reduce(&p[i]) < 0) {
exit(2);
}
else
exit(0);
}
static void
{
int i;
for (i = 0; i < NPTS; i++) {
break;
}
}
/*
* Parses command string for one graph parameter
* found in p->spec, placing field names in p->c[j].name,
* operators in p->c[j].op, and ranges in p->mn, p->mx, p->min, and p->max
*/
static void
parse(struct p *p)
{
int n, j;
char f[11][18];
char *strcpy();
"%s %s %s %s %s %s %s %s %s %s %s ",
f[0], f[1], f[2], f[3], f[4], f[5],
f[6], f[7], f[8], f[9], f[10]);
if (n % 2 == 0)
p->spec);
for (j = 0; j < n; j += 2) {
if (j == n-1) {
break;
else {
break;
}
}
if (DEBUG) {
for (n = 0; n <= j/2; n++)
}
}
static void
char *Targ)
{
extern char cmd[];
char plotfile[20];
int i;
int a, b;
/* Construct graph commands for left edge labels */
plotfile);
for (i = 1; i <= nplot; i++)
for (i = 1; i <= nplot; i++)
}
/* Construct graph commands for bottom labels and title */
plotfile);
0., .22, xlab_s,
for (i = 1; i <= nplot; i++)
.05, (.18 -.18*(float)(i-1)/5),
}
/* Form grid */
"graph -x %.3f %.3f -y 0 1 -r .1 -h .8 -u .2 -g 1 -s >> %s",
/* Construct graph commands for plotting, nplot cases */
for (i = 1; i <= nplot; i++) {
if (p[i].mode == 0)
".1 -h .8 -u .2 -g 0 -s -m %d -c \"%c\" >> %s",
else
".1 -h .8 -u .2 -g 0 -s -m 0 >> %s",
plotfile);
break;
/* b data missing */
a++;
/* error - a missing */
b++;
} else { /* a & b hr agree */
if (p[i].mode == 0)
else
"%.3f %.3f \"%c\"\n",
/*
* Test which index can be incremented without
* incurring a change in ..hr
*/
/* a free, b constrained */
a++;
/* a constrained, b free */
b++;
else {
/* Both free or constrained */
a++;
b++;
}
}
}
}
}
}
int
{
int i, j;
for (i = 0; i < 4; ) {
if (DEBUG) {
}
case '+':
case '-':
for (j = i; j < i+2; j++)
return (-1);
break;
case '\0':
return (-1);
if (i == 0)
return (0);
else
goto muldiv;
break;
default:
i++;
break;
}
}
if (DEBUG)
for (j = 0; j < 2; j++)
return (-1);
}
return (0);
}
static void
char *xlab_e)
{
/*
* Scans each data set to find and label those that contain
* multiple entries. Also truncates data values to fit within
* given plotting limits, or if unspecified, finds max value
* over all such data sets and sets their limits.
* If p[0] contains "time" values, its limits are taken from
* the -s and -e args.
*/
float yrange();
char *strcpy();
int i = 0;
int j;
float maxd = -1000;
float hrb;
p[0].mode = 0;
i = 1;
}
for (; i <= nplot; i++) {
p[i].mode = 0;
hrb = 0;
for (j = 0; j < NPTS; j++) {
break;
if (p[i].max > 0) {
}
else
p[i].mode = 1;
}
if (i == 0) {
if (p[0].max == 0) {
p[0].min = 0;
maxd = -1000;
}
}
}
/*
* Now that data range has been found, set limits of unspecified
* cases
*/
for (i = 1; i <= nplot; i++)
if (p[i].max == 0) {
p[i].min = 0;
if (p[i].max == 0)
p[i].max = 1.;
}
}