/*
* 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 <ctype.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
void
{
verbose_emit ^= 1;
}
/*
* Internal "emit".
* Note log_emit gathers up characters and issues a syslog or write to
* error log file if enabled.
*/
void
{
if (verbose_emit)
if (c == '\n') {
env->output_column = 0;
env->output_line++;
} else if (c == '\r')
env->output_column = 0;
else
env->output_column++;
if ((c >= 0x20 && c <= 0x7f) || c == '\n' || c == '\r' ||
c == '\b')
putchar(c);
else if (c < 0x20)
else
printf("\\%x", c);
}
log_emit(c);
}
void
{
}
void
{
fstack_t d;
}
/*
* 'key?' - abort if stdin is not a tty.
*/
void
{
int ret;
else
} else
}
/*
* 'key' - abort if stdin is not a tty, will block on read if char not avail.
*/
void
{
uchar_t c;
} else
}
void
{
int len;
char *ptr;
while (len--)
}
void
{
}
void
{
}
void
{
}
void
{
}
void
{
int len;
if (rbuf) {
} else
}
void
{
}
void
{
fstack_t d;
if (d) {
}
}
void
{
long ms;
}
struct CMN_MSG_T {
int level;
int len;
};
struct CMN_FMT_T {
};
static int cmn_msg_level = 0;
/*
* validfmt()
*
* Called by fmt_str() function to validate and extract formatting
* information from the supplied input buffer.
*
* Supported formats are:
* %c - character
* %d - signed decimal
* %x - unsigned hex
* %s - string
* %ld - signed 64 bit data
* %lx - unsigned 64 bit data
* %p - unsigned 64 bit data(pointer)
* %% - print as single "%" character
*
* Return values are:
* 0 - valid formatting
* 1 - invalid formatting found in the input buffer
* -1 - NULL pointer passed in for caller's receptacle
*
*
* For valid formatting, caller's supplied cmn_fmt_t elements are
* filled in:
* fwidth:
* > 0 - returned value is the field width
* < 0 - returned value is negation of field width for
* 64 bit data formats
* cwidth:
* formatted column width(if specified), otherwise 0
*
* format:
* contains the formatting(single) character
*/
static int
{
int isll = 0;
char *format;
return (-1);
/* check for left justification character */
if (*fmt == '-') {
fmt++;
(*fwidth)++;
/* check for column width specification */
fmt++;
(*fwidth)++;
}
/* if ljust specified w/o size, return format error */
if (*fwidth == 1) {
return (1);
}
} else {
/* check for column width specification */
fmt++;
(*fwidth)++;
}
}
}
/* if a column width was specified, save it in caller's struct */
if (dig1) {
int nbytes;
/* if too many digits in the width return error */
if (nbytes > CMN_MAX_DIGITS)
return (1);
}
/* check for long format specifier */
if (*fmt == 'l') {
fmt++;
(*fwidth)++;
isll = 1;
}
/* process by specific format type */
switch (*fmt) {
case 'c':
case 's':
case '%':
if (isll)
return (1);
case 'd':
case 'x':
(*fwidth)++;
break;
case 'p':
(*fwidth)++;
break;
default:
return (1); /* unknown format type */
}
if (isll) {
*fwidth *= -1;
}
return (0);
}
/*
* fmt_args()
*
* Called by fmt_str() to setup arguments for subsequent snprintf()
* calls. For cases not involving column width limitations, processing
* simply POPs the data stack as required to setup caller's arg(or
* llarg, as appropriate). When a column width is specified for output,
* a temporary buffer is constructed to contain snprintf() generated
* output for the argument. Testing is then performed to determine if
* the specified column width will require truncation of the output.
* If so, truncation of least significant digits is performed as
* necessary, and caller's arg(or llarg) is adjusted to obtain the
* specified column width.
*
*/
static void
long long *llarg)
{
char *cbuf;
int cbsize;
if (fw > 0) { /* check for normal (not long) formats */
/* initialize format string for snprintf call */
snf[0] = '%';
snf[2] = 0;
/* process by format type */
switch (format) {
case 'x':
cnv = 16;
case 'd':
case 'c':
case 'p':
break;
case 's':
break;
case '%':
return;
default:
"fmt_args:invalid format type! (%s)\n",
&format);
return;
}
/* check if a column width was specified */
if (cw) {
/* allocate a scratch buffer */
"fmt_args: snprintf output error\n");
ndigits++;
/* if truncation is necessary, do it */
if (format == 's') {
char *str;
} else
}
}
} else { /* process long formats */
/* check if a column width was specified */
if (cw) {
/* allocate a scratch buffer */
switch (format) {
case 'p':
cnv = 16;
"fmt_args: snprintf error\n");
break;
case 'x':
cnv = 16;
"fmt_args: snprintf error\n");
break;
case 'd':
"fmt_args: snprintf error\n");
break;
default:
"invalid long format type! (l%s)\n",
&format);
return;
}
ndigits++;
}
/* if truncation is necessary, do it */
}
}
}
}
/*
* fmt_str()
*
* Extracts text from caller's input buffer, processes explicit
* formatting as necessary, and outputs formatted text to caller's
* receptacle.
*
* env - pointer to caller's fcode environment
* fmt - pointer to caller's input buffr
* fmtbuf - ponter to caller's receptacle buffer
* bsize - size of caller's fmtbuf buffer
*
* This function performs an initial test to determine if caller's
* input buffer contains formatting(specified by presence of "%")
* in the buffer. If so, validfmt() function is called to verify
* the formatting, after which the buffer is processed according
* to the field width specified by validfmt() output. Special
* processing is required when caller's buffer contains a double
* "%" ("%%"), in which case the second "%" is accepted as normal
* text.
*/
static void
{
long arg;
long long llarg;
*fmtbuf = 0;
int vferr;
if (!vferr) {
} else {
if (vferr < 0) {
"fmt_str: NULL ptr supplied to validfmt()\n");
return;
}
bytes += 2;
"fmt_str: invalid format type! (%s)\n",
return;
}
if (fw > 0) { /* process normal (not long) formats */
} else {
/* if here, fw must be a long format */
if (*fmptr == 'p') {
} else {
}
}
/* if more input buffer to process, recurse */
}
/* call to extract args for snprintf() calls below */
if (fw > 0) { /* process normal (not long) formats */
switch (*fmptr) {
case 'd':
case 'x':
case 'c':
case 's':
case 'p':
break;
case '%':
break;
default:
"fmt_str: invalid format (%s)\n",
fmptr);
return;
}
} else /* process long formats */
} else
}
/*
* fc_cmn_append()
*
* Pops data stack to obtain message text, and calls fmt_str()
* function to perform any message formatting necessary.
*
* This function is called from fc_cmn_end() or directly in
* processing a cmn-append token. Since a pre-existing message
* context is assumed, initial checking is performed to verify
* its existence.
*/
void
{
int len;
char *str;
"fc_cmn_append: no message context for append\n");
return;
}
} else
"fc_cmn_append: append exceeds max msg size\n");
}
/*
* fc_cmn_end()
*
* Process ]cmn-end token to log the message initiated by a preceeding
* fc_cmn_start() call.
*
* Since nested cmn-xxx[ calls are supported, a test is made to determine
* if this is the final cmn-end of a nested sequence. If so, or if
* there was no nesting, log_message() is called with the appropriate
* text buffer. Otherwise, the root variable is adjusted to point to
* the preceeding message in the sequence and links in the list are
* updated. No logging is performed until the final ]cmn-end of the
* sequence is processed; then, messages are logged in FIFO order.
*/
void
{
if (root == 0) {
return;
}
do {
} while (root);
} else {
}
}
/*
* fc_cmn_start()
*
* Generic function to begin a common message.
*
* Allocates a new cmn_msg_t to associate with the message, and sets
* up initial text as specified by callers' inputs:
*
* env - pointer to caller's fcode environment
* head - pointer to initial text portion of the message
* path - flag to indicate if a device path is to be generated
*/
static void
{
char *dpath;
if (root != 0)
}
}
/*
* fc_cmn_type()
*
* Process cmn-type[ token.
*
* Invokes fc_cmn_start() to create a message containing blank
* header and no device path information.
*/
void
{
}
/*
* fc_cmn_msg()
*
* Process cmn-msg[ token.
*
* Invokes fc_cmn_start() to create a message containing blank
* header but specifying device path information.
*/
void
{
}
/*
* fc_cmn_note()
*
* Process cmn-note[ token.
*
* Invokes fc_cmn_start() to create a message with NOTICE stamping in
* the header and specification of device path information.
*/
void
{
}
/*
* fc_cmn_warn()
*
* Process cmn-warn[ token.
*
* Invokes fc_cmn_start() to create a message with WARNING stamping in
* the header and specification of device path information.
*/
void
{
}
/*
* fc_cmn_error()
*
* Process cmn-error[ token.
*
* Invokes fc_cmn_start() to create a message with ERROR stamping in
* the header and specification of device path information.
*/
void
{
}
/*
* fc_cmn_fatal()
*
* Process cmn-fatal[ token.
*
* Invokes fc_cmn_start() to create a message with FATAL stamping in
* the header and specification of device path information.
*/
void
{
}
static void
_init(void)
{
}