/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
*
* this module expands things like $file.$n in "templates".
* calling kw_init() sets the current "filename" used for
* $file, $dirname, and $basename.
*
* any time-based expansions, like $secs, or all the strftime()
* percent sequences, are based on the exact same point in time.
* so calling kw_expand() on something like "file-%T" will return
* the same thing when called multiple times during the same logadm run.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <libintl.h>
#include <stdlib.h>
#include <sys/systeminfo.h>
#include <strings.h>
#include <time.h>
#include <ctype.h>
#include <zone.h>
#include "err.h"
#include "lut.h"
#include "fn.h"
#include "kw.h"
/* forward declarations for functions used internally by this module */
/*
* absurdly long length to hold sprintf of a %d,
* or strftime() expansion of a *single* percent sequence
*/
/*
* kw_init -- initialize keywords based on given filename
*/
void
{
static char *fullpath;
static char *nfullpath;
static char *splitpath;
static char *home;
static char *user;
static char *logname;
static int initialized;
char *ptr;
/* make a copy of the string for $file */
if (fullpath)
/* make a copy of the string for $nfile */
if (nfullpath)
} else {
}
/* make a copy of the string for $dirname/$basename */
if (splitpath)
} else {
*ptr++ = '\0';
}
if (initialized)
return; /* rest of the keywords don't change */
else
else
else
else
initialized = 1;
}
/* helper function for kw_print() */
static void
{
}
/*
* kw_print -- spew the entire keywords table to stream
*
* this routine is used to dump the keywords table for debugging.
*/
void
{
}
/*
* kw_expand -- expand src into dst with given n value for $n (or $N)
*
* n == -1 means expand src into a reglob
* if gz is true, include ".gz" extension
*
* returns true if template contains $n or $N (implying rotation of files)
*/
{
int c;
char *ptr;
switch (c) {
case '.':
case '(':
case ')':
case '^':
case '+':
case '{':
case '}':
/* when building an re, escape with a backslash */
if (n < 0)
break;
case '?':
/* when building an re, change '?' to a single dot */
if (n < 0)
break;
case '*':
/* when building an re, change '*' to ".*" */
if (n < 0)
break;
case '$':
/* '$' marks the start of a keyword */
case '$':
/* double '$' stands for a single '$' */
if (n < 0)
break;
case '#':
/*
* $# expands to nothing, but forces an end
* of keyword, allow juxtaposition of a
* keyword with lower-case characters
*/
break;
case 'n':
case 'N':
/*
* we've found $n or $N, if we're
* building an re, build one that
* matches a number, otherwise
* expand the keyword to the n
* passed in to this function
*/
if (n < 0)
else {
MAXDIGITS, "%d",
(c == 'n') ? n : n + 1);
}
break;
}
/*FALLTHROUGH*/
default:
/* gather up the keyword name */
/* lookup keyword */
/* nope, copy it unexpanded */
if (n < 0)
} else
}
break;
case '%':
/*
* % sequence for strftime(), if we're building
* an re, we take our best guess at the re for
* this sequence, otherwise we pass it to strftime()
*/
if (n < 0) {
/*
* the regex for a percent sequence is
* usually just ".*" unless it is one
* of the common cases we know about
* that are numeric. in those cases, we
* tighten up the regex to just match digits.
*
* while it is gross that we embed knowledge
* of strftime() sequences here, they are
* specified in a standard so aren't
* expected to change often, and it *really*
* cuts down on the possibility that we'll
* expire a file that isn't an old log file.
*/
} else
switch (c) {
case 'd':
case 'g':
case 'G':
case 'H':
case 'I':
case 'j':
case 'm':
case 'M':
case 'S':
case 'u':
case 'U':
case 'V':
case 'w':
case 'W':
case 'y':
case 'Y':
/* pure numeric cases */
break;
case 'e':
case 'k':
case 'l':
/* possible space then num */
break;
case 'D': /* %m/%d/%y */
/* adds slashes! */
"[0-9]+/[0-9]+/[0-9]+");
break;
case 'R': /* %H:%M */
break;
case 'T': /* %H:%M:%S */
"[0-9]+:[0-9]+:[0-9]+");
break;
default:
}
} else {
/* copy % sequence to tbuf */
tbuf[0] = '%';
/* "extended" sequence */
} else
/* just copy %x */
else
}
break;
default:
/* nothing special, just copy it */
}
if (gz) {
if (n < 0)
else
}
return (hasn);
}
#ifdef TESTMODULE
/*
* test main for kw module, usage: a.out fname [template...]
*/
int
{
int i;
if (argc < 2)
err(0, "first arg must be fname");
for (i = 2; i < argc; i++) {
int n;
for (n = -1; n < 2; n++) {
printf("expand<%s> n %d hasn %d ",
}
}
err_done(0);
/* NOTREACHED */
return (0);
}
#endif /* TESTMODULE */