[comp.sys.atari.st] setenv on boot-up

csrobe@ICASE.EDU (Charles S. [Chip] Roberson) (03/15/89)

I'm almost sure this problem has been discussed, answered, and a program
supplied, but I can't remember the answer and can't find the program.
I would like to set some environment variables upon boot-up to last
for as long as the ST is on.  How do I do this?

Thanks!
-c
+-------------------------------------------------------------------------+
|Charles S. Roberson          ARPANET:  csrobe@icase.edu                  |
|Dept. of Comp. Sci.                    csrobe@cs.wm.edu                  |
|College of William and Mary  BITNET:   $csrobe@wmmvs.bitnet              |
|Williamsburg, VA  23185      UUCP:     ...!uunet!pyrdc!gmu90x!wmcs!csrobe|
| (804) 229-5530              COMING SOON: csr@endor.uucp                 |
+-------------------------------------------------------------------------+

to_stdnet@stag.UUCP (03/19/89)

From: dal@syntel.UUCP (Dale Schumacher)

[csrobe@ICASE.EDU (Charles S. [Chip] Roberson) writes...]
> I'm almost sure this problem has been discussed, answered, and a program
> supplied, but I can't remember the answer and can't find the program.
> I would like to set some environment variables upon boot-up to last
> for as long as the ST is on.  How do I do this?

The problem here is "at boot-up".  I assume you want a program to put
in the /AUTO/ folder that will set the desired environment variables.
The problem is, when the /AUTO/ folder programs are being run, the
desktop has not yet been started.  This fact is how the following
function determines if a program is running from the /AUTO/ folder,
the desktop or some child of the desktop (a shell).

camefrom()
	{
	register BASEPAGE *p = _base;
	register int n = 0;

	p = p->p_parent;
	if((((long) (p->p_tbase)) & 0x800000L) == 0L)
		return(FROM_SHELL);
	while(p = p->p_parent)
		++n;
	return((n == 1) ? FROM_AUTO : ((n == 2) ? FROM_DESKTOP : FROM_SHELL));
	}

To do what you want requires you to set the desktop's environment,
which is obviously not possible until the desktop is running.  However,
once the desktop IS running, the following program will set the PATH
variable as an example of how the desktop's environment can be changed.
Note that this program MUST BE RUN FROM THE DESKTOP to work properly.
It should probably contain a call to camefrom() to verify this.

/*
 *  setpath	- Set the PATH environment variable for the GEM desktop.
 *		  by Dale Schumacher  <dal@syntel.uucp>
 */

#include <stdio.h>
#include <basepage.h>

extern	char	*_envp;

/* pick ONLY ONE of the following two choices */
#define	TOS_STYLE	1	/* add TOS-style variables */
#define	MWC_STYLE	0	/* add MWC-style variables */

static char *findenv(var)
	register char *var;
/*
 *	INTERNAL FUNCTION.  This functions attempts to locate <var> in
 *	the environment.  If <var> is not found, NULL is returned.  If
 *	the environment is NULL, NULL is returned.  If <var> is found,
 *	a pointer to the beginning of <var> in the environment is returned.
 *	BOTH MS-DOS AND TOS ENVIRONMENT FORMATS ARE ACCOMODATED.
 */
	{
	register char *p;
	register int len;

	if((p = _envp) == NULL)
		return(NULL);
	len = strlen(var);
	while(*p)
		{
		if((p[len] == '=') && !strncmp(p, var, len))
			return(p);
		while(*p++)		/* move to next arg */
			;
		}
	return(NULL);
	}

char *getenv(var)
	register char *var;
/*
 *	Search for <var> in the environment.  If <var> is found, a pointer
 *	to it's value is returned.  NULL is returned if <var> is not found.
 *	WARNING:  The returned pointer points into the environment and
 *	must not be modified!
 */
	{
	register char *p, *q;
	register int len;

	len = strlen(var);
	if(p = findenv(var))
		{
		p += (len + 1);
		if(*p == '\0')		/* TOS env format or empty value */
			{
			q = p+1;
			if(*q == '\0')		/* empty value + end of env */
				return(p);
			while(*q && (*q != '='))
				++q;
			if(*q)			/* empty value */
				return(p);
			else			/* TOS env format */
				return(p+1);
			}
		}
	return(p);
	}

int putenv(entry)
	char *entry;
/*
 *	Add <entry> to the environment.  <entry> can be any of the following
 *	forms:
 *		<VARIABLE>
 *		<VARIABLE>=
 *		<VARIABLE>=<value>
 *	The first form removes <VARIABLE> from the environment.  getenv()
 *	will return NULL if looking for this variable.  The second form adds
 *	<VARIABLE> to the environment, with a null value.  getenv() will
 *	return a pointer to a '\0' character if looking for this variable.
 *	Many environment handlers don't support such "tag variables", so
 *	their use is not recommended.  The final form is the most common,
 *	and safest to use.  <VARIABLE> is installed (or replaced) with the
 *	value <value>.  It should be noted that this function itself is not
 *	supported in many systems and should be used will care to prevent
 *	overflowing the space allocated for the environment.
 */
	{
	register char *p, *q, *t, c;
	register int len;

	for(t=entry; (c = *t) && (c != '='); ++t)
		;
	*t = '\0';
	if(p = getenv(entry))		/* remove old var */
		{
		q = p;
		while(*q++)			/* find end of old val */
			;
		p -= (len = strlen(entry));
		while(strncmp(--p, entry, len))	/* find start of old var */
			;
		while(*q)			/* copy environment tail */
			while(*p++ = *q++)
				;
		*p++ = '\0';			/* tie off environment */
		*p = 0xFF;
		}
	if(c == '=')					/* install new var */
		{
		p = _envp;
		while(*p)			/* find end of env */
			while(*p++)
				;
#if MWC_STYLE
		*t = c;
		q = entry;
		while(*p++ = *q++)		/* copy new entry */
			;
#endif
#if TOS_STYLE
		q = entry;
		while(*p++ = *q++)		/* copy new var */
			;
		*--p = '=';
		*++p = '\0';
		while(*p++ = *q++)		/* copy new value */
			;
		*t = c;
#endif
		*p++ = '\0';			/* tie off environment */
		*p = 0xFF;
		}
	return(TRUE);
	}

main(argc, argv)
	int argc;
	char *argv[];
/*
 *	Assume that this program is being called from the desktop.
 *	To change the PATH for the desktop, you modify the environment
 *	of the parent process (the desktop).
 */
	{
	char path[256];
	register BASEPAGE *bp;

	if(argc != 2)
		{
		fprintf(stderr, "usage: SETPATH <command search path>\n");
		getch();
		exit(EXIT_FAILURE);
		}
	sprintf(path, "PATH=%s", argv[1]);
	bp = _base->p_parent;			/* locate parent's basepage */
	_envp = bp->p_env;			/* get environment pointer */
	putenv(path);
	}


--
      Dale Schumacher                         399 Beacon Ave.
      (alias: Dalnefre')                      St. Paul, MN  55104
      ...bungia!cctb!syntel!dal               United States of America
             "I may be competitive, but I'm never ruthless"
 

kbad@atari.UUCP (Ken Badertscher) (03/27/89)

Dale posts some very useful code for dealing with environment variables.
However, the part of the code that deals with the TOS environment will
hopefully be obsolete very soon.  The fact that there is a null after
the PATH= in the default TOS environment string is an anachronism left
over from a bug in earlier TOS versions, to wit; the BIOS variable which
holds the value of the boot device was used as a WORD instead of as
a BYTE when filling the startup environment string, hence you get a null
before the drive letter.
  This is not standard, nor should it be construed as a "TOS" format
environment.  The easiest way to check for the default environment is
with a couple of longword compares (look for "PATH" then
"=;\0<bootdev>" <- really four characters there, =, ;, <null>, A or C  ).
GEMDOS environment strings are:
	...a series of null-terminated strings of the format
	"VAR=value"; the last string is followed by two zero
	bytes, indicating the end of the environment.
						- Pexec Cookbook
Which is to say, they follow the somewhat universal environment string
standard, a'la UNIX(tm) or MS-DOS(tm).  The fact that semicolons were
required to separate path names was an oversight as well; TOS 1.4 allows
commas or semicolons to separate pathnames in the PATH environment
variable. In fact, the AES now uses the environment much more
intelligently, and will look down whatever paths you have specified for
shel_find and rsrc_load calls.
 
   Hopefully someday I'll get to release the auto/accessory environment
setting utility that I've written; I think people will like being able
to stick their resources all in one folder...

-- 
 Ken Badertscher                 | #include <disclaimer>
 Atari R&D Software Engine       | GEMDOS LIVES! ...or is that Frodo?
 {portal,ames,imagen}!atari!kbad | I can never remember these things...

root@TSfR.UUCP (usenet) (03/29/89)

In article <1407@atari.UUCP> kbad@atari.UUCP (Ken Badertscher) writes:

>The fact that there is a null after
>the PATH= in the default TOS environment string is an anachronism left
>over from a bug in earlier TOS versions...

 Pity that it lasted so long, because it does create another way of doing
 environments.  Having it there forces getenv() to understand both NAME=<0>
 and NAME= environment structures. You might as well say it's the standard
 format, unless you're gonna take that misfeature out in 1.4, because getenv
 will have to know how to parse it anyway.

>	...a series of null-terminated strings of the format
>	"VAR=value"; the last string is followed by two zero
>	bytes, indicating the end of the environment.
>						- Pexec Cookbook

 Where can this developer get a copy of the Pexec cookbook? Or, for that
 matter, SALAD? It might solve some of the `invent-our-own' standards
 problems if the docs were more widely available.

>   Hopefully someday I'll get to release the auto/accessory environment
>setting utility that I've written; I think people will like being able
>to stick their resources all in one folder...

 You mean the desktop?  Oh, gross! :-)

   -david parsons
   -orc@pell.uucp

ralph@laas.laas.fr (Ralph P. Sobek) (03/30/89)

In article <747@stag.UUCP>, to_stdnet@stag.UUCP writes:
> From: dal@syntel.UUCP (Dale Schumacher)
> 
> [csrobe@ICASE.EDU (Charles S. [Chip] Roberson) writes...]
> > I'm almost sure this problem has been discussed, answered, and a program
> > supplied, but I can't remember the answer and can't find the program.
> > I would like to set some environment variables upon boot-up to last
> > for as long as the ST is on.  How do I do this?
> 
 [Dale Schumacher describes a nice source solution!]

There exists in the GEMBOOT package by Konrad Hahn, the function
DESKENV.TTP which sets environment variables.  I've tested it and it
works with Gulam, and arc.  It should be available (I got mine from
AtariNet, if I remember).

-- 
Ralph P. Sobek			  Disclaimer: The above ruminations are my own.
ralph@laas.laas.fr			   Addresses are ordered by importance.
ralph@laas.uucp, or ...!uunet!mcvax!laas!ralph		If all else fails, try:
SOBEK@FRMOP11.BITNET				      sobek@eclair.Berkeley.EDU