archie/prospero/lib/pfs/penviron.c
2024-05-27 16:13:40 +02:00

487 lines
14 KiB
C

/*
* Copyright (c) 1989, 1990, 1991 by the University of Washington
* Copyright (c) 1991, 1992, 1993 by the University of Southern California
*
* For copying and distribution information, please see the files
* <uw-copyright.h> and <usc-copyr.h>.
*/
#include <uw-copyright.h>
#include <usc-copyr.h>
#include <pcompat.h>
#include <pfs.h>
#include <psite.h>
#include <pmachine.h>
#include <perrno.h>
#ifdef SOLARIS
/* #include "p_solaris_stdlib.h" \* Special tricks to prototype setenv() */
#else
#include <stdlib.h> /* For malloc and free, getenv etc */
#endif
static char vsroot_host[MAX_VPATH] = "";
static char vsroot_file[MAX_VPATH] = "";
static char vswork_host[MAX_VPATH] = "";
static char vswork_file[MAX_VPATH] = "";
static char vswork[MAX_VPATH] = "";
static char vshome_host[MAX_VPATH] = "";
static char vshome_file[MAX_VPATH] = "";
static char vshome[MAX_VPATH] = "";
static char vsdesc_host[MAX_VPATH] = "";
static char vsdesc_file[MAX_VPATH] = "";
static char vsname[MAX_VPATH] = "";
/*
* Note that there is one more environment variable used, PFS_DEFAULT,
* but that environment variable is per process and is handled in the
* pcompat library.
*/
#ifdef PUTENV /* If we don't have the lib. function */
static setenv();
#endif
void
pset_wd(wdhost,wdfile,wdname)
char *wdhost;
char *wdfile;
char *wdname;
{
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
if(wdhost) {
strcpy(vswork_host,wdhost);
setenv("VSWORK_HOST",wdhost,1);
}
if(wdfile) {
strcpy(vswork_file,wdfile);
setenv("VSWORK_FILE",wdfile,1);
}
if(wdname) {
strcpy(vswork,wdname);
setenv("VSWORK",wdname,1);
}
}
char * pget_wdhost()
{
char *env_st;
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
if(!*vswork_host && (env_st = getenv("VSWORK_HOST")))
strcpy(vswork_host,env_st);
if(*vswork_host) return(vswork_host);
else return(NULL);
}
char * pget_wdfile()
{
char *env_st;
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
if(!*vswork_file && (env_st = getenv("VSWORK_FILE")))
strcpy(vswork_file,env_st);
if(*vswork_file) return(vswork_file);
else return(NULL);
}
char * pget_wd()
{
char *env_st;
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
if(!*vswork && (env_st = getenv("VSWORK")))
strcpy(vswork,env_st);
if(*vswork) return(vswork);
else return(NULL);
}
void
pset_hd(hdhost,hdfile,hdname)
char *hdhost;
char *hdfile;
char *hdname;
{
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
if(hdhost) {
strcpy(vshome_host,hdhost);
setenv("VSHOME_HOST",hdhost,1);
}
if(hdfile) {
strcpy(vshome_file,hdfile);
setenv("VSHOME_FILE",hdfile,1);
}
if(hdname) {
strcpy(vshome,hdname);
setenv("VSHOME",hdname,1);
}
}
char * pget_hdhost()
{
char *env_st;
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
if(!*vshome_host && (env_st = getenv("VSHOME_HOST")))
strcpy(vshome_host,env_st);
if(*vshome_host) return(vshome_host);
else return(NULL);
}
char * pget_hdfile()
{
char *env_st;
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
if(!*vshome_file && (env_st = getenv("VSHOME_FILE")))
strcpy(vshome_file,env_st);
if(*vshome_file) return(vshome_file);
else return(NULL);
}
char * pget_hd()
{
char *env_st;
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
if(!*vshome && (env_st = getenv("VSHOME")))
strcpy(vshome,env_st);
if(*vshome) return(vshome);
else return(NULL);
}
void
pset_rd(rdhost,rdfile)
char *rdhost;
char *rdfile;
{
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
if(rdhost) {
strcpy(vsroot_host,rdhost);
setenv("VSROOT_HOST",rdhost,1);
}
if(rdfile) {
strcpy(vsroot_file,rdfile);
setenv("VSROOT_FILE",rdfile,1);
}
}
char * pget_rdhost()
{
char *env_st;
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
if(!*vsroot_host && (env_st = getenv("VSROOT_HOST")))
strcpy(vsroot_host,env_st);
if(*vsroot_host) return(vsroot_host);
else return(NULL);
}
char * pget_rdfile()
{
char *env_st;
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
if(!*vsroot_file && (env_st = getenv("VSROOT_FILE")))
strcpy(vsroot_file,env_st);
if(*vsroot_file) return(vsroot_file);
else return(NULL);
}
void
pset_desc(dhost,dfile,vsnm)
char *dhost;
char *dfile;
char *vsnm;
{
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
if(dhost) {
strcpy(vsdesc_host,dhost);
setenv("VSDESC_HOST",dhost,1);
}
if(dfile) {
strcpy(vsdesc_file,dfile);
setenv("VSDESC_FILE",dfile,1);
}
if(vsnm) {
strcpy(vsname,vsnm);
setenv("VSNAME",vsnm,1);
}
}
char * pget_dhost()
{
char *env_st;
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
if(!*vsdesc_host && (env_st = getenv("VSDESC_HOST")))
strcpy(vsdesc_host,env_st);
if(*vsdesc_host) return(vsdesc_host);
else return(NULL);
}
char * pget_dfile()
{
char *env_st;
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
if(!*vsdesc_file && (env_st = getenv("VSDESC_FILE")))
strcpy(vsdesc_file,env_st);
if(*vsdesc_file) return(vsdesc_file);
else return(NULL);
}
char * pget_vsname()
{
char *env_st;
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
if(!*vsname && (env_st = getenv("VSNAME")))
strcpy(vsname,env_st);
if(*vsname) return(vsname);
else return(NULL);
}
/*
* Pprint shell string prints command on the standard output which when
* interpreted by the shell will set environment variable and define
* aliases needed to pass the prospero environment from program to
* program. This routine is called by vfsetup and vcd.
*
* The argument is a bit vector indicating which variable should be set.
* The low order bit is (0x0):
*
* 0x001 Print aliases
* 0x002 Print virtual system description
* 0x004 Print working directory
* 0x008 Print home directory
* 0x010 Print root directory
* 0x1e0 Mask indicating which shell to print strings for. We leave room
* for 16 possibilities for when more shells with their own weird
* syntaxes show up.
*/
#define SHELL_MASK 0x1e0
#define SHELL_ERROR 0x0 /* 0 is undefined */
#define SHELL_SH 0x020
#define SHELL_CSH 0x040
void
p__print_shellstring(int which)
{
int shell = which & SHELL_MASK;
if((which & 0x1)&&(shell == SHELL_CSH)) {
printf("alias vwd 'echo $VSWORK';\n");
printf("alias vwp 'echo $VSWORK_HOST $VSWORK_FILE';\n");
printf("alias vwho 'echo $VSNAME';\n");
printf("alias vcd 'p__vcd -s csh \\!* >! /tmp/vfs$$;source /tmp/vfs$$;\
/bin/rm /tmp/vfs$$'\n");
#ifndef P_NO_PCOMPAT
printf("alias venable 'setenv PFS_DEFAULT %d;if($?Poldcd == 0) set Poldcd = `alias cd`;alias pwd vwd;alias cd vcd';\n",PMAP_ATSIGN_NF);
printf("set Presetcd = 'unalias cd;alias cd $Poldcd;unset Poldcd';\n");
printf("alias vdisable 'unsetenv PFS_DEFAULT;unalias pwd;if($?Poldcd) eval $Presetcd';\n");
#endif P_NO_PCOMPAT
} else if((which & 0x1)&&(shell == SHELL_SH)) {
printf("vwd () { echo $VSWORK \n}\n");
printf("vwp () { echo $VSWORK_HOST $VSWORK_FILE \n}\n");
printf("vwho () { echo $VSNAME \n}\n");
printf("vcd () { p__vcd -s sh $* > /tmp/vfs$$ ;. /tmp/vfs$$; /bin/rm /tmp/vfs$$ \n}\n");
#ifndef P_NO_PCOMPAT
/* Note that this will bash any existing cd alias */
printf("venable () { PFS_DEFAULT=%d;export PFS_DEFAULT;alias cd=vcd;alias pwd=vwd \n}\n",PMAP_ATSIGN_NF);
printf("vdisable () { unset PFS_DEFAULT;unalias cd; unalias pwd\n}\n");
#endif P_NO_PCOMPAT
}
if((which & 0x2)&&(shell == SHELL_CSH)) {
printf("setenv VSDESC_HOST \"%s\";\n",pget_dhost());
printf("setenv VSDESC_FILE \"%s\";\n",pget_dfile());
printf("setenv VSNAME \"%s\";\n",pget_vsname());
}
else if((which & 0x2)&&(shell == SHELL_SH)) {
printf("VSDESC_HOST=\"%s\";export VSDESC_HOST\n",pget_dhost());
printf("VSDESC_FILE=\"%s\";export VSDESC_FILE\n",pget_dfile());
printf("VSNAME=\"%s\";export VSNAME\n",pget_vsname());
}
if((which & 0x4)&&(shell == SHELL_CSH)) {
printf("setenv VSWORK_HOST \"%s\";\n",pget_wdhost());
printf("setenv VSWORK_FILE \"%s\";\n",pget_wdfile());
printf("setenv VSWORK \"%s\";\n",pget_wd());
}
else if((which & 0x4)&&(shell == SHELL_SH)) {
printf("VSWORK_HOST=\"%s\";export VSWORK_HOST\n",pget_wdhost());
printf("VSWORK_FILE=\"%s\";export VSWORK_FILE\n",pget_wdfile());
printf("VSWORK=\"%s\";export VSWORK\n",pget_wd());
}
if((which & 0x8)&&(shell == SHELL_CSH)) {
printf("setenv VSHOME_HOST \"%s\";\n",pget_hdhost());
printf("setenv VSHOME_FILE \"%s\";\n",pget_hdfile());
printf("setenv VSHOME \"%s\";\n",pget_hd());
}
else if((which & 0x8)&&(shell == SHELL_SH)) {
printf("VSHOME_HOST=\"%s\";export VSHOME_HOST\n",pget_hdhost());
printf("VSHOME_FILE=\"%s\";export VSHOME_FILE\n",pget_hdfile());
printf("VSHOME=\"%s\";export VSHOME\n",pget_hd());
}
if((which & 0x10)&&(shell == SHELL_CSH)) {
printf("setenv VSROOT_HOST \"%s\";\n",pget_rdhost());
printf("setenv VSROOT_FILE \"%s\";\n",pget_rdfile());
}
else if((which & 0x10)&&(shell == SHELL_SH)) {
printf("VSROOT_HOST=\"%s\";export VSROOT_HOST\n",pget_rdhost());
printf("VSROOT_FILE=\"%s\";export VSROOT_FILE\n",pget_rdfile());
}
}
/* return a flag value for the shell that can be given to
p__print_shellstring(). If no shell defined, return 0 and set
p_err_string. This functions is only called by the VCD and VFSETUP
commands at this time. */
int
p__get_shellflag(const char *shellname)
{
char *shellenvar;
int shellenvarlen;
if (shellname) {
if (strequal(shellname, "sh")) return SHELL_SH;
if (strequal(shellname, "csh")) return SHELL_CSH;
p_err_string = qsprintf_stcopyr(p_err_string,
"The system doesn't know about shells of type \"%s\". \
Please see the person who maintains Prospero at your site.", shellname);
perrno = PFAILURE;
return SHELL_ERROR;
}
/* this part is going to go away eventually. The -s flag to p__vfsetup and
p__vcd has effectively obsoleted it. It's still around for a while, (a)
in case people are using old versions of vfsetup.source or
vfsetup.profil. and (b) because I'm too sentimental to flush it yet :).
*/
shellenvar = getenv("SHELL");
if (!shellenvar) {
p_err_string = qsprintf_stcopyr(p_err_string,
"Couldn't find SHELL environment variable; \
I don't know what kind of SHELL you're using. Please see your maintainer.");
perrno = PFAILURE;
return SHELL_ERROR; /* undefined */
}
shellenvarlen = strlen(shellenvar);
if (shellenvarlen >= 3 && strequal(shellenvar + shellenvarlen - 3, "csh"))
return SHELL_CSH;
else
return SHELL_SH;
}
#ifdef PUTENV
static int
setenv(char *n,char *v, int o)
{
int tmp;
/* Allocate space for environment variable */
char *template = (char *) stalloc(strlen(n)+strlen(v)+2);
sprintf(template,"%s=%s",n,v);
tmp = putenv(template);
return(tmp);
/* Potential memory leak - it is not clear whether putenv */
/* deallocates the string with the old value of the */
/* envorinment variable. If not, then we should do so here. */
/* This concern is not valid (swa, 5/27/93):
From the SUN OS 4.1.3 manual page for 'putenv()':
int putenv(string)
char *string;
"the string pointed to by string becomes part of the environment, so
altering the string will change the environment. "
The HP-UX 8.05 manual page is similarly worded.
*/
}
#endif PUTENV
#ifdef BADSETENV
/*
* Copyright (c) 1987 Regents of the University of California.
* This file may be freely redistributed provided that this
* notice remains attached.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)setenv.c 1.2 (Berkeley) 3/13/87";
#endif LIBC_SCCS and not lint
#include <sys/types.h>
#include <stdio.h>
/*
* setenv(name,value,rewrite)
* Set the value of the environmental variable "name" to be
* "value". If rewrite is set, replace any current value.
*/
setenv(name,value,rewrite)
register char *name,
*value;
int rewrite;
{
extern char **environ;
static int alloced; /* if allocated space before */
register char *C;
int l_value,
offset;
char *_findenv();
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
if (*value == '=') /* no `=' in value */
++value;
l_value = strlen(value);
if ((C = _findenv(name,&offset))) { /* find if already exists */
if (!rewrite)
return(0);
#if BUG
if (strlen(C) <= l_value) { /* smaller; copy over */
while (*C++ = *value++);
return(0);
}
#else
if (l_value <= strlen(C)) { /* smaller; copy over */
while (*C++ = *value++);
return(0);
}
#endif BUG
}
else { /* create new slot */
register int cnt;
register char **P;
for (P = environ,cnt = 0;*P;++P,++cnt);
if (alloced) { /* just increase size */
environ = (char **)realloc((char *)environ,
(u_int)(sizeof(char *) * (cnt + 2)));
if (!environ)
return(-1);
}
else { /* get new space */
alloced = 1; /* copy old entries into it */
P = (char **)malloc((u_int)(sizeof(char *) *
(cnt + 2)));
if (!P)
return(-1);
bcopy(environ,P,cnt * sizeof(char *));
environ = P;
}
environ[cnt + 1] = NULL;
offset = cnt;
}
for (C = name;*C && *C != '=';++C); /* no `=' in name */
if (!(environ[offset] = /* name + `=' + value */
malloc((u_int)((int)(C - name) + l_value + 2))))
return(-1);
for (C = environ[offset];(*C = *name++) && *C != '=';++C);
for (*C++ = '=';*C++ = *value++;);
return(0);
}
#endif BADSETENV