Пример #1
0
/*
 * lut_lookup -- find an entry
 */
void *
lut_lookup(struct lut *root, const char *lhs)
{
	int diff;

	if (root == NULL || lhs == NULL)
		return (NULL);
	else if ((diff = strcmp(root->lut_lhs, lhs)) == 0)
		return (root->lut_rhs);
	else if (diff > 0)
		return (lut_lookup(root->lut_left, lhs));
	else
		return (lut_lookup(root->lut_right, lhs));
}
Пример #2
0
static int build_lookup(struct timecode_def *def)
{
    unsigned int n;
    bits_t current, last;

    if (def->lookup)
        return 0;

    fprintf(stderr, "Building LUT for %d bit %dHz timecode (%s)\n",
            def->bits, def->resolution, def->desc);

    if (lut_init(&def->lut, def->length) == -1)
	return -1;

    current = def->seed;

    for (n = 0; n < def->length; n++) {
        /* timecode must not wrap */
        dassert(lut_lookup(&def->lut, current) == (unsigned)-1);
        lut_push(&def->lut, current);
        last = current;
        current = fwd(current, def);
        dassert(rev(current, def) == last);
    }

    def->lookup = true;

    return 0;
}
Пример #3
0
struct ipath *
ipath_for_usednames(struct node *np)
{
	struct ipath *ret, *ipp;
	int i = 0;
	struct node *np2;

	for (np2 = np; np2 != NULL; np2 = np2->u.name.next)
		i++;
	ret = MALLOC(sizeof (*ret) * (i + 1));
	for (i = 0, np2 = np; np2 != NULL; np2 = np2->u.name.next) {
		ret[i].s = np2->u.name.s;
		ret[i++].i = 0;
	}
	ret[i].s = NULL;
	if ((ipp = lut_lookup(Ipaths, (void *)ret,
	    (lut_cmp)ipath_cmp)) != NULL) {
		FREE(ret);
		return (ipp);
	}
	Ipaths = lut_add(Ipaths, (void *)ret, (void *)ret, (lut_cmp)ipath_cmp);
	stats_counter_bump(Nipath);
	stats_counter_add(Nbytes, (i + 1) * sizeof (struct ipath));
	return (ret);
}
Пример #4
0
struct ipath *
ipath_dummy(struct node *np, struct ipath *ipp)
{
	struct ipath *ret;

	ret = ipp;
	while (ipp[1].s != NULL)
		ipp++;
	if (strcmp(ipp[0].s, np->u.name.last->u.name.s) == 0)
		return (ret);

	ret = MALLOC(sizeof (*ret) * 2);
	ret[0].s = np->u.name.last->u.name.s;
	ret[0].i = 0;
	ret[1].s = NULL;
	if ((ipp = lut_lookup(Ipaths, (void *)ret,
	    (lut_cmp)ipath_cmp)) != NULL) {
		FREE(ret);
		return (ipp);
	}
	Ipaths = lut_add(Ipaths, (void *)ret, (void *)ret, (lut_cmp)ipath_cmp);
	stats_counter_bump(Nipath);
	stats_counter_add(Nbytes, 2 * sizeof (struct ipath));
	return (ret);
}
Пример #5
0
void
printer(const char *lhs, void *rhs, void *arg)
{
	struct lut *root = (struct lut *)arg;

	printf("<%s> <%s> (<%s>)\n", lhs, (char *)rhs,
	    (char *)lut_lookup(arg, lhs));
}
Пример #6
0
/*
 * conf_opts -- return the parsed opts for an entry
 */
struct opts *
conf_opts(const char *lhs)
{
	struct confinfo *cp = lut_lookup(Conflut, lhs);

	if (cp != NULL)
		return (cp->cf_opts);
	return (opts_parse(NULL, NULL, OPTF_CONF));
}
Пример #7
0
/*
 * conf_lookup -- lookup an entry in the config file
 */
void *
conf_lookup(const char *lhs)
{
	struct confinfo *cp = lut_lookup(Conflut, lhs);

	if (cp != NULL)
		err_fileline(Confname, cp->cf_lineno);
	return (cp);
}
Пример #8
0
/*
 * ipath -- find instanced path in cache, or add it if necessary
 */
const struct ipath *
ipath(struct node *np)
{
	struct ipath *ret;
	int count;
	struct node *namep;
	int i;

	if ((ret = lut_lookup(Ipaths, (void *)np,
	    (lut_cmp)ipath_epnamecmp)) != NULL)
		return (ret);	/* already in cache */

	/*
	 * not in cache, make new cache entry.
	 * start by counting the length of the name.
	 */
	count = 0;
	namep = np;
	while (namep != NULL) {
		ASSERTinfo(namep->t == T_NAME, ptree_nodetype2str(namep->t));
		count++;
		namep = namep->u.name.next;
	}

	ASSERT(count > 0);

	/* allocate array for name and last NULL entry */
	ret = MALLOC(sizeof (*ret) * (count + 1));
	ret[count].s = NULL;

	/* fill in ipath entry */
	namep = np;
	i = 0;
	while (namep != NULL) {
		ASSERT(i < count);
		ret[i].s = namep->u.name.s;
		if (namep->u.name.child != NULL &&
		    namep->u.name.child->t == T_NUM)
			ret[i].i = (int)namep->u.name.child->u.ull;
		else
			config_getcompname(namep->u.name.cp, NULL, &ret[i].i);
		i++;
		namep = namep->u.name.next;
	}

	/* add it to the cache */
	Ipaths = lut_add(Ipaths, (void *)ret, (void *)ret,
	    (lut_cmp)ipath_cmp);

	stats_counter_bump(Nipath);
	stats_counter_add(Nbytes, (count + 1) * sizeof (struct ipath));

	return (ret);
}
Пример #9
0
/*
 * conf_set -- set options for an entry in the config file
 */
void
conf_set(const char *entry, char *o, const char *optarg)
{
	struct confinfo *cp = lut_lookup(Conflut, entry);

	if (Conffd == -1)
		return;

	if (cp != NULL) {
		if (cp->cf_opts == NULL)
			cp->cf_opts = opts_parse(cp->cf_args, OPTF_CONF);
		cp->cf_flags &= ~CONFF_DELETED;
	} else {
		fillconflist(0, STRDUP(entry), NULL,
		    opts_parse(NULL, OPTF_CONF), NULL, 0);
		if ((cp = lut_lookup(Conflut, entry)) == NULL)
			err(0, "conf_set internal error");
	}
	(void) opts_set(cp->cf_opts, o, optarg);
	Confchanged = B_TRUE;
}
Пример #10
0
/*
 * conf_set -- set options for an entry in the config file
 */
void
conf_set(const char *entry, char *o, const char *optarg)
{
	struct confinfo *cp = lut_lookup(Conflut, entry);

	if (Conffd == -1)
		return;

	if (cp != NULL) {
		cp->cf_flags &= ~CONFF_DELETED;
	} else {
		fillconflist(0, STRDUP(entry),
		    opts_parse(NULL, NULL, OPTF_CONF), NULL, 0);
		if ((cp = lut_lookup(Conflut, entry)) == NULL)
			err(0, "conf_set internal error");
	}
	(void) opts_set(cp->cf_opts, o, optarg);
	if (strcmp(o, "P") == 0)
		Changed |= CHG_TIMES;
	else
		Changed = CHG_BOTH;
}
Пример #11
0
/*
 * conf_opts -- return the parsed opts for an entry
 */
struct opts *
conf_opts(const char *lhs)
{
	struct confinfo *cp = lut_lookup(Conflut, lhs);

	if (cp != NULL) {
		if (cp->cf_opts)
			return (cp->cf_opts);	/* already parsed */
		err_fileline(Confname, cp->cf_lineno);
		cp->cf_opts = opts_parse(cp->cf_args, OPTF_CONF);
		return (cp->cf_opts);
	}
	return (opts_parse(NULL, OPTF_CONF));
}
Пример #12
0
/*
 * conf_replace -- replace an entry in the config file
 */
void
conf_replace(const char *lhs, struct opts *newopts)
{
	struct confinfo *cp = lut_lookup(Conflut, lhs);

	if (Conffd == -1)
		return;

	if (cp != NULL) {
		cp->cf_opts = newopts;
		cp->cf_args = NULL;
		if (newopts == NULL)
			cp->cf_flags |= CONFF_DELETED;
	} else
		fillconflist(0, lhs, NULL, newopts, NULL, 0);
	Confchanged = B_TRUE;
}
Пример #13
0
/*
 * scan the memory image of a file
 *	returns: 0: error, 1: ok, 3: -P option found
 */
static int
conf_scan(const char *fname, char *buf, int buflen, int timescan,
    struct opts *cliopts)
{
	int ret = 1;
	int lineno = 0;
	char *line;
	char *eline;
	char *ebuf;
	char *entry, *comment;

	ebuf = &buf[buflen];

	if (buf[buflen - 1] != '\n')
		err(EF_WARN|EF_FILE, "file %s doesn't end with newline, "
		    "last line ignored.", fname);

	for (line = buf; line < ebuf; line = eline) {
		char *ap;
		struct opts *opts = NULL;
		struct confinfo *cp;

		lineno++;
		err_fileline(fname, lineno);
		eline = line;
		comment = NULL;
		for (; eline < ebuf; eline++) {
			/* check for continued lines */
			if (comment == NULL && *eline == '\\' &&
			    eline + 1 < ebuf && *(eline + 1) == '\n') {
				*eline = ' ';
				*(eline + 1) = ' ';
				lineno++;
				err_fileline(fname, lineno);
				continue;
			}

			/* check for comments */
			if (comment == NULL && *eline == '#') {
				*eline = '\0';
				comment = (eline + 1);
				continue;
			}

			/* check for end of line */
			if (*eline == '\n')
				break;
		}
		if (comment >= ebuf)
			comment = NULL;
		if (eline >= ebuf) {
			/* discard trailing unterminated line */
			continue;
		}
		*eline++ = '\0';

		/*
		 * now we have the entry, if any, at "line"
		 * and the comment, if any, at "comment"
		 */

		/* entry is first token */
		entry = nexttok(&line);
		if (entry == NULL) {
			/* it's just a comment line */
			if (!timescan)
				fillconflist(lineno, entry, NULL, comment, 0);
			continue;
		}
		if (strcmp(entry, "logadm-version") == 0) {
			/*
			 * we somehow opened some future format
			 * conffile that we likely don't understand.
			 * if the given version is "1" then go on,
			 * otherwise someone is mixing versions
			 * and we can't help them other than to
			 * print an error and exit.
			 */
			if ((entry = nexttok(&line)) != NULL &&
			    strcmp(entry, "1") != 0)
				err(0, "%s version not supported "
				    "by this version of logadm.",
				    fname);
			continue;
		}

		/* form an argv array */
		ArgsI = 0;
		while (ap = nexttok(&line))
			fillargs(ap);
		Args[ArgsI] = NULL;

		LOCAL_ERR_BEGIN {
			if (SETJMP) {
				err(EF_FILE, "cannot process invalid entry %s",
				    entry);
				ret = 0;
				LOCAL_ERR_BREAK;
			}

			if (timescan) {
				/* append to config options */
				cp = lut_lookup(Conflut, entry);
				if (cp == NULL) {
					/* orphaned entry */
					if (opts_count(cliopts, "v"))
						err(EF_FILE, "stale timestamp "
						    "for %s", entry);
					LOCAL_ERR_BREAK;
				}
				opts = cp->cf_opts;
			}
			opts = opts_parse(opts, Args, OPTF_CONF);
			if (!timescan) {
				fillconflist(lineno, entry, opts, comment, 0);
			}
		LOCAL_ERR_END }

		if (ret == 1 && opts && opts_optarg(opts, "P") != NULL)
			ret = 3;
	}

	err_fileline(NULL, 0);
	return (ret);
}
Пример #14
0
/*
 * 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)
 */
boolean_t
kw_expand(struct fn *src, struct fn *dst, int n, boolean_t gz)
{
	int c;
	char buf[MAXDIGITS];
	boolean_t hasn = B_FALSE;
	struct fn *kw = fn_new(NULL);
	char *ptr;
	struct tm *gmt_tm = localtime(&Now);

	while ((c = fn_getc(src)) != '\0')
		switch (c) {
		case '.':
		case '(':
		case ')':
		case '^':
		case '+':
		case '{':
		case '}':
			/* when building an re, escape with a backslash */
			if (n < 0)
				fn_putc(dst, '\\');
			fn_putc(dst, c);
			break;
		case '?':
			/* when building an re, change '?' to a single dot */
			if (n < 0)
				fn_putc(dst, '.');
			break;
		case '*':
			/* when building an re, change '*' to ".*" */
			if (n < 0)
				fn_putc(dst, '.');
			fn_putc(dst, '*');
			break;
		case '$':
			/* '$' marks the start of a keyword */
			switch (c = fn_getc(src)) {
			case '$':
				/* double '$' stands for a single '$' */
				if (n < 0)
					fn_putc(dst, '\\');
				fn_putc(dst, '$');
				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':
				if (c == 'N' || !islower(fn_peekc(src))) {
					/*
					 * 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
					 */
					hasn = B_TRUE;
					if (n < 0)
						fn_puts(dst, "([0-9]+)$0");
					else {
						(void) snprintf(buf,
						    MAXDIGITS, "%d",
						    (c == 'n') ? n : n + 1);
						fn_puts(dst, buf);
					}
					break;
				}
				/*FALLTHROUGH*/
			default:
				/* gather up the keyword name */
				fn_renew(kw, NULL);
				fn_putc(kw, c);
				while (islower(fn_peekc(src)))
					fn_putc(kw, fn_getc(src));

				/* lookup keyword */
				if ((ptr = (char *)lut_lookup(Keywords,
				    fn_s(kw))) == NULL) {
					/* nope, copy it unexpanded */
					if (n < 0)
						fn_putc(dst, '\\');
					fn_putc(dst, '$');
					fn_putfn(dst, kw);
				} else
					fn_puts(dst, ptr);
			}
			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.
				 */
				if ((c = fn_getc(src)) == 'E' || c == 'O') {
					c = fn_getc(src);
					fn_puts(dst, ".*");
				} 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 */
						fn_puts(dst, "[0-9]+");
						break;
					case 'e':
					case 'k':
					case 'l':
						/* possible space then num */
						fn_puts(dst, " *[0-9]+");
						break;
					case 'D':	/* %m/%d/%y */
						/* adds slashes! */
						fn_puts(dst,
						    "[0-9]+/[0-9]+/[0-9]+");
						break;
					case 'R':	/* %H:%M */
						fn_puts(dst, "[0-9]+:[0-9]+");
						break;
					case 'T':	/* %H:%M:%S */
						fn_puts(dst,
						    "[0-9]+:[0-9]+:[0-9]+");
						break;
					default:
						fn_puts(dst, ".*");
					}
			} else {
				char tbuf[4];

				/* copy % sequence to tbuf */
				tbuf[0] = '%';
				tbuf[1] = fn_getc(src);
				if (tbuf[1] == 'E' || tbuf[1] == 'O') {
					/* "extended" sequence */
					tbuf[2] = fn_getc(src);
					tbuf[3] = '\0';
				} else
					tbuf[2] = '\0';

				if (strftime(buf, MAXDIGITS, tbuf, gmt_tm) == 0)
					/* just copy %x */
					fn_puts(dst, tbuf);
				else
					fn_puts(dst, buf);
			}
			break;
		default:
			/* nothing special, just copy it */
			fn_putc(dst, c);
		}

	if (gz) {
		if (n < 0)
			fn_puts(dst, "(\\.gz){0,1}");
		else
			fn_puts(dst, ".gz");
	}

	fn_free(kw);
	return (hasn);
}
Пример #15
0
const unsigned long long *
lex_s2ullp_lut_lookup(struct lut *root, const char *s)
{
    return ((unsigned long long *)lut_lookup(root, (void *)s, NULL));
}
Пример #16
0
static int
lex_s2i_lut_lookup(struct lut *root, const char *s)
{
    return ((intptr_t)lut_lookup(root, (void *)s, NULL));
}