fmdump.c revision 7ee93e3bbce920c0d0742deb6632b0939e30b783
/*
* 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.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <alloca.h>
#include <unistd.h>
#include <limits.h>
#include <strings.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <errno.h>
#include <time.h>
#include <ctype.h>
#include <fmdump.h>
#define FMDUMP_EXIT_SUCCESS 0
#define FMDUMP_EXIT_FATAL 1
#define FMDUMP_EXIT_USAGE 2
#define FMDUMP_EXIT_ERROR 3
const char *g_pname;
char *g_root;
/*PRINTFLIKE2*/
void
{
g_errs++;
}
}
void
{
g_errs++;
}
/*PRINTFLIKE1*/
void
fmdump_warn(const char *format, ...)
{
}
char *
{
fmdump_warn("record time is too large for 32-bit utility\n");
} else {
}
return (buf);
}
char *
{
#ifdef _ILP32
fmdump_warn("record time is too large for 32-bit utility\n");
} else {
#endif
#ifdef _ILP32
}
#endif
return (buf);
}
static int
{
"[-T time] [-u uuid] [file]\n", g_pname);
"\t-c select events that match the specified class\n"
"\t-e display error log content instead of fault log content\n"
"\t-f follow growth of log file by waiting for additional data\n"
"\t-R set root directory for pathname expansions\n"
"\t-t select events that occurred after the specified time\n"
"\t-T select events that occurred before the specified time\n"
"\t-u select events that match the specified uuid\n"
"\t-v set verbose mode: display additional event detail\n"
"\t-V set very verbose mode: display complete event contents\n");
return (FMDUMP_EXIT_USAGE);
}
/*ARGSUSED*/
static int
{
fmdump_warn("skipping record: %s\n",
return (0);
}
/*
* Yet another disgusting argument parsing function (TM). We attempt to parse
* a time argument in a variety of strptime(3C) formats, in which case it is
* interpreted as a local time and is converted to a timeval using mktime(3C).
* If those formats fail, we look to see if the time is a decimal integer
* followed by one of our magic suffixes, in which case the time is interpreted
* as a time delta *before* the current time-of-day (i.e. "1h" = "1 hour ago").
*/
static struct timeval *
gettimeopt(const char *arg)
{
const struct {
const char *name;
} suffix[] = {
{ NULL }
};
char *p;
}
}
/*
* First try a variety of strptime() calls. If these all fail, we'll
* try parsing an integer followed by one of our suffix[] strings.
* NOTE: any form using %y must appear *before* the equivalent %Y form;
* otherwise %Y will accept the two year digits but infer century zero.
* Any form ending in %y must additionally check isdigit(*p) to ensure
* that it does not inadvertently match 2 digits of a 4-digit year.
*
* Beware: Any strptime() sequence containing consecutive %x sequences
* may fall victim to SCCS expanding it as a keyword! If this happens
* we use separate string constant that ANSI C will concatenate.
*/
int i;
errno = 0;
}
break;
}
}
}
}
} else if (*p == '\0' || *p == '.') {
/*
* If tm_year is zero, we matched [%b %d] %H:%M[:%S]; use
* the result of localtime(&tod.tv_sec) to fill in the rest.
*/
if (d > 0) {
}
}
errno = 0;
}
/*
* If our mktime() set tm_isdst, adjust the result for DST by
* subtracting the offset between the main and alternate zones.
*/
if (p[0] == '.') {
arg = p;
errno = 0;
}
}
} else {
}
return (tvp);
}
/*
* If the -u option is specified in combination with the -e option, we iterate
* over each record in the fault log with a matching UUID finding xrefs to the
* error log, and then use this function to iterate over every xref'd record.
*/
int
{
int i, rv = 0;
}
return (rv);
}
int
{
}
/*
* If the -a option is not present, filter out fault records that correspond
* to events that the producer requested not be messaged for administrators.
*/
/*ARGSUSED*/
int
{
}
int
{
int iflags = 0;
const fmdump_ops_t *ops;
void *farg;
int c, err;
switch (c) {
case 'a':
opt_a++;
break;
case 'c':
break;
case 'e':
opt_e++;
break;
case 'f':
opt_f++;
break;
case 'H':
opt_H++;
break;
case 'O':
break;
case 'R':
break;
case 't':
break;
case 'T':
break;
case 'u':
opt_u++;
opt_a++; /* -u implies -a */
break;
case 'v':
opt_v++;
break;
case 'V':
opt_V++;
break;
default:
}
}
if (*ifile != '\0') {
return (FMDUMP_EXIT_USAGE);
} else {
}
}
}
if (*ifile == '\0') {
"when file operand is present\n", g_pname);
return (FMDUMP_EXIT_USAGE);
}
return (FMDUMP_EXIT_FATAL);
}
if (opt_H) {
return (FMDUMP_EXIT_SUCCESS);
}
return (FMDUMP_EXIT_FATAL);
}
ops = &fmdump_err_ops;
ops = &fmdump_flt_ops;
ops = &fmdump_asru_ops;
else
ops = &fmdump_err_ops;
}
if (opt_V) {
} else if (opt_v) {
} else
if (iflags & FMD_LOG_XITER_OFFS)
} else {
}
if (iflags & FMD_LOG_XITER_OFFS) {
}
do {
g_errs++;
}
if (opt_f)
(void) sleep(1);
} while (opt_f);
}