5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CDDL HEADER START
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * The contents of this file are subject to the terms of the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Common Development and Distribution License (the "License").
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * You may not use this file except in compliance with the License.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * or http://www.opensolaris.org/os/licensing.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * See the License for the specific language governing permissions
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * and limitations under the License.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * When distributing Covered Code, include this CDDL HEADER in each
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If applicable, add the following below this CDDL HEADER, with the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner]
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CDDL HEADER END
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Use is subject to license terms.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* All Rights Reserved */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <limits.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <string.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <stdlib.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <unistd.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <ctype.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* 0 = both upper and lower case */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* 1 = initial lower case only (build variables) */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* 2 = initial upper case only (install variables) */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define mode(flag, pt) (!flag || ((flag == 1) && islower(pt[1])) || \
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ((flag == 2) && isupper(pt[1])))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * For next and last functions below, values indicate whether resolution
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * was possible.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 0 = all OK - the variable resolved within the established parameters
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * or it wasn't time for the variable to bind.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 1 = parameter did not resolve because there was no value in the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * environment or because it was a build variable at install
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * time.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This gets a raw path which may contain shell variables and returns in path
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a pathname with all appropriate parameters resolved. If it comes in
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * relative, it goes out relative.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandmappath(int flag, char *path)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char buffer[PATH_MAX];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char varname[64];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *npt, *pt, *pt2, *copy;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *token;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int retvalue = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland copy = buffer;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * For each "/" separated token. If the token contains an environment
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * variable, then evaluate the variable and insert it into path.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (pt = path; *pt; /* void */) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If this is a token and it's an environment variable
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * properly situated in the path...
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((*pt == '$') && isalpha(pt[1]) &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ((pt == path) || (pt[-1] == '/'))) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* ... and it's the right time to evaluate it... */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (mode(flag, pt)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* replace the parameter with its value. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pt2 = varname;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (npt = pt+1; *npt && (*npt != '/');
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* void */)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *pt2++ = *npt++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *pt2 = '\0';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * At this point EVERY token should evaluate
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * to a value. If it doesn't, there's an
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * error.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((token = getenv(varname)) != NULL &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *token != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* copy in parameter value */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (*token)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *copy++ = *token++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pt = npt;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retvalue = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *copy++ = *pt++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If evaluate time is wrong, determine of this is an
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * error.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (flag == 2) { /* install-time. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ALL variables MUST evaluate at
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * install time.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *copy++ = *pt++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retvalue = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if (flag == 1 && /* build-time */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland islower(pt[1])) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * All build-time variables must
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * evaluate at build time.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retvalue = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *copy++ = *pt++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else /* no problem. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *copy++ = *pt++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If it's a separator, copy it over to the target buffer and
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * move to the start of the next token.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if (*pt == '/') {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (pt[1] == '/')
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pt++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((pt[1] == '\0') && (pt > path))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *copy++ = *pt++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If we're in the middle of a non-parametric token, copy
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * that character over and try the next character.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *copy++ = *pt++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *copy = '\0';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strcpy(path, buffer);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (retvalue);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This function resolves the path into an absolute path referred to
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * an install root of ir.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandvoid
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandbasepath(char *path, char *basedir, char *ir)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char buffer[PATH_MAX];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* For a relative path, prepend the basedir */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (*path != '/') {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strcpy(buffer, path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ir && *ir) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (*ir)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *path++ = *ir++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (path[-1] == '/')
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland path--;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (basedir && *basedir) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ir && *ir && *basedir != '/')
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *path++ = '/';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (*basedir)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *path++ = *basedir++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (path[-1] == '/')
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland path--;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *path++ = '/';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strcpy(path, buffer);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* For an absolute path, just prepend the install root */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ir && *ir) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strcpy(buffer, path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (*ir)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *path++ = *ir++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (path[-1] == '/')
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland path--;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strcpy(path, buffer);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Evaluate varname and return with environment variables resolved.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * NOTE: This assumes that varname is a buffer long enough to hold the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * evaluated string.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandmapvar(int flag, char *varname)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *token;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int retvalue = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* If its a parametric entry beginning with an alpha character. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (*varname == '$' && isalpha(varname[1])) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* ...and it's the right time to evaluate it... */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (mode(flag, varname)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * then it MUST be possible to evaluate it. If not,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * there's an error.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (((token = getenv(&varname[1])) != NULL) &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *token) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* copy token into varname */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (*token)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *varname++ = *token++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *varname = '\0';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retvalue = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (flag == 2) /* install-time. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ALL variables MUST evaluate at install
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * time.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retvalue = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else if (flag == 1 && /* build-time */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland islower(varname[1]))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * all build-time variables must evaluate at
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * build time.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retvalue = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (retvalue);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}