OpenSolaris_b135/cmd/fmli/oh/odikey.c

Compare this file to the similar file:
Show the results in this format:

/*
 * 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
 * or http://www.opensolaris.org/os/licensing.
 * 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, 1985, 1986, 1987, 1988, 1989 AT&T	*/
/*	  All Rights Reserved  	*/

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#include <stdio.h>
#include <sys/types.h>		/* EFT abs k16 */
#include "wish.h"
#include "typetab.h"
#include "var_arrays.h"
#include "moremacros.h"
#include "sizes.h"

#define ODISIZ (2*PATHSIZ)
#define NULLSTR	""

static char *copy_to_key();
static char *skip_to_key();

int
odi_putkey(entry, key, value)
struct ott_entry *entry;
char *key, *value;
{
	int length;
	register char *p, *q;
	char valbuf[PATHSIZ], odibuf[ODISIZ];
	char *copy_to_key(), *skip_to_key();

	if (key == NULL)
		key = NULLSTR;
	if (value == NULL)
		value = NULLSTR;

	if ((length = strlen(value) + strlen(key)) >= sizeof(valbuf))
		return(O_FAIL);
	if (entry->odi && (strlen(entry->odi) + length >= ODISIZ))
		return(O_FAIL);

	strcpy(valbuf, key);
	strcat(valbuf, "=");
	q = value;
	for (p=valbuf+strlen(valbuf); (*q!='\0') && (p < valbuf+PATHSIZ); p++,q++) {
		switch (*q) {
		case ';':
		case '=':
		case '\\':
			*p++ = '\\';
			/* no break */
		default:
			*p = *q;
		}
	}
	*p = '\0';

	if (entry->odi == NULL) {		/* no odi, just add it */
		entry->odi = strsave(valbuf);
		return(O_OK);
	}

	/* copy the new value onto beginning of odibuf, then copy all of
	 * the old odibuf onto the end, leaving out the original key if
	 * it exists.
	 */
	strcpy(odibuf, valbuf);

	strcpy(valbuf, key);
	strcat(valbuf, "=");
	length = strlen(valbuf);
	q = entry->odi;
	for (p = &odibuf[strlen(odibuf)]; *q; ) {
		if (strncmp(q, valbuf, length) == 0)
			q = skip_to_key(q);
		else {
			*p++ = ';';
			q = copy_to_key(p, q, sizeof(odibuf) - (p-odibuf), FALSE);
			p = p + strlen(p);
		}
	}
	*p = '\0';

	free(entry->odi);
	entry->odi = strsave(odibuf);
	return(O_OK);
}

char *
odi_getkey(entry, key)
struct ott_entry *entry;
char *key;
{
	register int length;
	register char *p;
	static char keybuf[PATHSIZ];

	char *copy_to_key(), *skip_to_key();

	strcpy(keybuf, key);
	strcat(keybuf, "=");
	length = strlen(keybuf);

	for (p = entry->odi; p && *p; p = skip_to_key(p)) {
		if (strncmp(keybuf, p, length) == 0) {
			copy_to_key(keybuf, p+length, sizeof(keybuf), TRUE);
			break;
		}
	}
	if (p && *p)
		return(keybuf);
	else
		return(NULL);
}

/* copy from src to dst one keyword's value, of maximum size sizedst.
 * If unquote is TRUE, then the copy should also remove a level of backslashes.
 */

static char *
copy_to_key(dst, src, sizedst, unquote)
char *dst, *src;
int sizedst;
bool unquote;
{
	register char *p = dst;
	register bool done = FALSE;

	while (!done && src && *src && dst-p < sizedst-1 ) {
		switch (*src) {
		case ';':
			done = TRUE;
			break;
		case '\\':
			if (src[1]) {
				if (unquote == FALSE)
					*dst++ = *src;
				src++;
			}
			/* no break! continue with next case */
		default:
			*dst++ = *src++;
			break;
		}
	}
	*dst = '\0';
	return(done?++src:src);		/* skip the ";" */
}

static char *
skip_to_key(src)
char *src;
{
	char dst[PATHSIZ];

	return(copy_to_key(dst, src, sizeof(dst), TRUE));
}

/* return the first entry in the current ott which has key set to
 * value.
 */

struct ott_entry *
key_to_odi(key, value)
char *key, *value;
{
	extern struct ott_entry *Cur_entry;

	register int i;
	register int size = array_len(Cur_entry);
	register char *p;


	for (i = 0; i < size; i++)
		if ((p = odi_getkey(Cur_entry[i].dname, key)) && strcmp(p, value) == 0)
			return(Cur_entry + i);

	return(NULL);
}