Revision: 1.14, Tue Feb 4 23:10:49 2003 UTC (2 years, 4 months ago) by jrasmuss23
Branch: MAIN
CVS Tags: aolserver_v4_r0_beta_16, aolserver_v4_r0_beta_20, aolserver_v4_r0_beta_21, aolserver_v4_r0_beta_4, aolserver_v4_r0_beta_3, aolserver_v4_r0_beta_13, aolserver_v4_r0_beta_7, aolserver_v4_r0_beta_6, aolserver_v4_r0_beta_5, aolserver_v4_r0_beta_12, aolserver_v4_r0_beta_9, aolserver_v40_r10, aolserver_v4_r0_beta_11, aolserver_v4_r0_beta_19, aolserver_v4_r0_beta_18, aolserver_v40_r9, aolserver_v40_r8, aolserver_v40_r7, aolserver_v40_r6, aolserver_v40_r5, aolserver_v4_r0_beta_10, aolserver_v40_r3, aolserver_v40_r2, aolserver_v40_r1, aolserver_v40_r0, aolserver_v4_r0_beta_15, aolserver_v4_r0_beta_14, aolserver_v4_r0_beta_8, aolserver_v4_r0_beta_2, aolserver_v4_r0_beta_17, aolserver_v40_r9_b2, HEAD
Branch point for: aolserver_v40_bp
Changes since 1.13: +2 -2 lines
Changes for Win32 support
/*
 * The contents of this file are subject to the AOLserver Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://aolserver.com/.
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is AOLserver Code and related documentation
 * distributed by AOL.
 * 
 * The Initial Developer of the Original Code is America Online,
 * Inc. Portions created by AOL are Copyright (C) 1999 America Online,
 * Inc. All Rights Reserved.
 *
 * Alternatively, the contents of this file may be used under the terms
 * of the GNU General Public License (the "GPL"), in which case the
 * provisions of GPL are applicable instead of those above.  If you wish
 * to allow use of your version of this file only under the terms of the
 * GPL and not to allow others to use your version of this file under the
 * License, indicate your decision by deleting the provisions above and
 * replace them with the notice and other provisions required by the GPL.
 * If you do not delete the provisions above, a recipient may use your
 * version of this file under either the License or the GPL.
 */


/* 
 * tclenv.c --
 *
 *	Implement the "ns_env" command.
 */

static const char *RCSID = "@(#) $Header: /cvsroot/aolserver/aolserver/nsd/tclenv.c,v 1.14 2003/02/04 23:10:49 jrasmuss23 Exp $, compiled: " __DATE__ " " __TIME__;

#include	"nsd.h"

static int PutEnv(Tcl_Interp *interp, char *name, char *value);
static Ns_Mutex lock;
#ifdef HAVE__NSGETENVIRON
#include <crt_externs.h>
#elif !defined(_WIN32)
extern char **environ;
#endif


/*
 *----------------------------------------------------------------------
 *
 * Ns_CopyEnviron --
 *
 *	Copy the environment to the given dstring along with
 *	an argv vector.
 *
 * Results:
 *	Pointer to dsPtr->string.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char **
Ns_CopyEnviron(Ns_DString *dsPtr)
{
    char *s, **envp;
    int i;

    Ns_MutexLock(&lock);
    envp = Ns_GetEnviron();
    for (i = 0; (s = envp[i]) != NULL; ++i) {
	Ns_DStringAppendArg(dsPtr, s);
    }
    Ns_MutexUnlock(&lock);
    return Ns_DStringAppendArgv(dsPtr);
}


/*
 *----------------------------------------------------------------------
 *
 * NsTclEnvCmd --
 *
 *	Implement the "env" command.  Read the code to see what it does.
 *	NOTE:  The getenv() and putenv() routines are assumed MT safe
 *	and there's no attempt to avoid the race condition between
 *	finding a variable and using it.  The reason is it's assumed
 *	the environment would only be modified, if ever, at startup.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Environment variables may be updated.
 *
 *----------------------------------------------------------------------
 */

int
NsTclEnvCmd(ClientData dummy, Tcl_Interp *interp, int argc, char **argv)
{
    char	*name, *value, **envp;
    int		status, i;
    Tcl_DString	ds;

    if (argc < 2) {
	Tcl_AppendResult(interp, "wrong # args:  should be \"",
		argv[0], " command ?args ...?\"", NULL);
	return TCL_ERROR;
    }

    status = TCL_OK;
    Ns_MutexLock(&lock);
    if (STREQ(argv[1], "names")) {
	if (argc != 2) {
	    Tcl_AppendResult(interp, "wrong # args:  should be \"",
		    argv[0], " names\"", NULL);
	    status = TCL_ERROR;
	} else {
	    Tcl_DStringInit(&ds);
    	    envp = Ns_GetEnviron();
	    for (i = 0; envp[i] != NULL; ++i) {
		name = envp[i];
		value = strchr(name, '=');
		Tcl_DStringAppend(&ds, name, value ? value - name : -1);
	    	Tcl_AppendElement(interp, ds.string);
		Tcl_DStringTrunc(&ds, 0);
	    }
	    Tcl_DStringFree(&ds);
	}

    } else if (STREQ(argv[1], "exists")) {
	if (argc != 3) {
	    Tcl_AppendResult(interp, "wrong # args:  should be \"",
		    argv[0], " exists name\"", NULL);
	    status = TCL_ERROR;
	} else {
	    Tcl_SetResult(interp, getenv(argv[2]) ? "1" : "0", TCL_STATIC);
	}

    } else if (STREQ(argv[1], "get")) {
	if ((argc != 3 && argc != 4) ||
		(argc == 4 && !STREQ(argv[2], "-nocomplain"))) {
badargs:
	    Tcl_AppendResult(interp, "wrong # args:  should be \"",
		    argv[0], " ", argv[1], " ?-nocomplain? name\"", NULL);
	    status = TCL_ERROR;
	}
	name = argv[argc-1];
	value = getenv(name);
	if (value != NULL) {
	    Tcl_SetResult(interp, value, TCL_VOLATILE);
	} else if (argc == 4) {
	    Tcl_AppendResult(interp, "no such environment variable: ",
		argv[argc-1], NULL);
	    status = TCL_ERROR;
	}

    } else if (STREQ(argv[1], "set")) {
	if (argc != 4) {
	    Tcl_AppendResult(interp, "wrong # args:  should be \"",
		    argv[0], " set name value\"", NULL);
	    status =  TCL_ERROR;
	} else {
	    status = PutEnv(interp, argv[2], argv[3]);
	}

    } else if (STREQ(argv[1], "unset")) {
	if ((argc != 3 && argc != 4) ||
		(argc == 4 && !STREQ(argv[2], "-nocomplain"))) {
	    goto badargs;
	}
	name = argv[argc-1];
	if (argc == 3 && getenv(name) == NULL) {
	    Tcl_AppendResult(interp, "no such environment variable: ", name,
			     NULL);
	    status = TCL_ERROR;
	} else {
	    status = PutEnv(interp, name, "");
	}

    } else {
	Tcl_AppendResult(interp, "unknown command \"",
		argv[1], "\": should be exists, names, get, set, or unset", NULL);
	status = TCL_ERROR;
    }

    Ns_MutexUnlock(&lock);
    return status;
}


/*
 *----------------------------------------------------------------------
 *
 * PutEnv --
 *
 *	NsTclEnvCmd helper routine to update an environment variable.
 *
 * Results:
 *	TCL_OK or TCL_ERROR.
 *
 * Side effects:
 *	Environment variable is set.
 *
 *----------------------------------------------------------------------
 */

static int
PutEnv(Tcl_Interp *interp, char *name, char *value)
{
    char *s;
    size_t len;

    len = strlen(name);
    if (value != NULL) {
	len += strlen(value) + 1;
    }
    /* NB: Use malloc() directly as putenv() would expect. */
    s = malloc(len + 1);
    if (s == NULL) {
	Tcl_SetResult(interp,
		"could not allocate memory for new env entry", TCL_STATIC);
	return TCL_ERROR;
    }
    strcpy(s, name);
    if (value != NULL) {
	strcat(s, "=");
	strcat(s, value);
    }
    if (putenv(s) != 0) {
	Tcl_AppendResult(interp, "could not put environment entry \"",
		s, "\": ", Tcl_PosixError(interp), NULL);
	free(s);
	return TCL_ERROR;
    }
    return TCL_OK;
}


/*
 *----------------------------------------------------------------------
 *
 * Ns_GetEnviron --
 *
 *	Return the environment vector.
 *
 * Results:
 *	Pointer to environment.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char **
Ns_GetEnviron(void)
{
   char **envp;

#ifdef HAVE__NSGETENVIRON
    envp = *_NSGetEnviron();
#else
    envp = environ;
#endif
    return envp;
}

Back to SourceForge.net

Powered by ViewCVS 1.0-dev